diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs
index 2c3b25b2e1c4..14d9b5480151 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs
@@ -74,6 +74,7 @@ protected override void ExtractInitializers(TextWriter trapFile)
{
case SyntaxKind.BaseConstructorInitializer:
initializerType = Symbol.ContainingType.BaseType!;
+ ExtractObjectInitCall(trapFile);
break;
case SyntaxKind.ThisConstructorInitializer:
initializerType = Symbol.ContainingType;
@@ -90,10 +91,12 @@ protected override void ExtractInitializers(TextWriter trapFile)
var primaryInfo = Context.GetSymbolInfo(primaryInitializer);
var primarySymbol = primaryInfo.Symbol;
+ ExtractObjectInitCall(trapFile);
ExtractSourceInitializer(trapFile, primarySymbol?.ContainingType, (IMethodSymbol?)primarySymbol, primaryInitializer.ArgumentList, primaryInitializer.GetLocation());
}
else if (Symbol.MethodKind is MethodKind.Constructor)
{
+ ExtractObjectInitCall(trapFile);
var baseType = Symbol.ContainingType.BaseType;
if (baseType is null)
{
@@ -127,6 +130,27 @@ protected override void ExtractInitializers(TextWriter trapFile)
}
}
+ private void ExtractObjectInitCall(TextWriter trapFile)
+ {
+ var target = ObjectInitMethod.Create(Context, ContainingType!);
+
+ var type = Context.Compilation.GetSpecialType(SpecialType.System_Void);
+
+ var info = new ExpressionInfo(Context,
+ AnnotatedTypeSymbol.CreateNotAnnotated(type),
+ Location,
+ Kinds.ExprKind.METHOD_INVOCATION,
+ this,
+ -2,
+ isCompilerGenerated: true,
+ null);
+ var obinitCall = new Expression(info);
+
+ trapFile.expr_call(obinitCall, target);
+
+ Expressions.This.CreateImplicit(Context, Symbol.ContainingType, Location, obinitCall, -1);
+ }
+
private void ExtractSourceInitializer(TextWriter trapFile, ITypeSymbol? type, IMethodSymbol? symbol, ArgumentListSyntax arguments, Microsoft.CodeAnalysis.Location location)
{
var initInfo = new ExpressionInfo(Context,
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/IMethodEntity.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IMethodEntity.cs
new file mode 100644
index 000000000000..278f2b18798e
--- /dev/null
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IMethodEntity.cs
@@ -0,0 +1,9 @@
+namespace Semmle.Extraction.CSharp.Entities
+{
+ ///
+ /// Marker interface for method entities.
+ ///
+ public interface IMethodEntity : IEntity
+ {
+ }
+}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs
index c1b0f1a65bcb..c92c561f31b6 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs
@@ -9,7 +9,7 @@
namespace Semmle.Extraction.CSharp.Entities
{
- internal abstract class Method : CachedSymbol, IExpressionParentEntity, IStatementParentEntity
+ internal abstract class Method : CachedSymbol, IExpressionParentEntity, IStatementParentEntity, IMethodEntity
{
protected Method(Context cx, IMethodSymbol init)
: base(cx, init) { }
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/ObjectInitMethod.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/ObjectInitMethod.cs
new file mode 100644
index 000000000000..ce07e56508db
--- /dev/null
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/ObjectInitMethod.cs
@@ -0,0 +1,56 @@
+using System.IO;
+using Microsoft.CodeAnalysis;
+
+namespace Semmle.Extraction.CSharp.Entities
+{
+ internal sealed class ObjectInitMethod : CachedEntity, IMethodEntity
+ {
+ private Type ContainingType { get; }
+
+ private ObjectInitMethod(Context cx, Type containingType)
+ : base(cx)
+ {
+ this.ContainingType = containingType;
+ }
+
+ public static readonly string Name = "