mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #15625 from michaelnebel/csharp/primaryconstructorinitializer
C# 12: Primary constructor inititalizers.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -10,8 +12,16 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class Constructor : Method
|
||||
{
|
||||
private readonly List<SyntaxNode> declaringReferenceSyntax;
|
||||
|
||||
private Constructor(Context cx, IMethodSymbol init)
|
||||
: base(cx, init) { }
|
||||
: base(cx, init)
|
||||
{
|
||||
declaringReferenceSyntax =
|
||||
Symbol.DeclaringSyntaxReferences
|
||||
.Select(r => r.GetSyntax())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
@@ -22,6 +32,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.constructors(this, Symbol.ContainingType.Name, ContainingType, (Constructor)OriginalDefinition);
|
||||
trapFile.constructor_location(this, Location);
|
||||
|
||||
if (IsPrimary)
|
||||
{
|
||||
// Create a synthetic empty body for primary constructors.
|
||||
Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location);
|
||||
}
|
||||
|
||||
if (Symbol.IsImplicitlyDeclared)
|
||||
{
|
||||
var lineCounts = new LineCounts() { Total = 2, Code = 1, Comment = 0 };
|
||||
@@ -33,68 +49,79 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
protected override void ExtractInitializers(TextWriter trapFile)
|
||||
{
|
||||
// Do not extract initializers for constructed types.
|
||||
if (!IsSourceDeclaration)
|
||||
return;
|
||||
|
||||
var syntax = Syntax;
|
||||
var initializer = syntax?.Initializer;
|
||||
|
||||
if (initializer is null)
|
||||
// Only extract initializers for constructors with a body and primary constructors.
|
||||
if (Block is null && ExpressionBody is null && !IsPrimary ||
|
||||
!IsSourceDeclaration)
|
||||
{
|
||||
if (Symbol.MethodKind is MethodKind.Constructor)
|
||||
return;
|
||||
}
|
||||
|
||||
if (OrdinaryConstructorSyntax?.Initializer is ConstructorInitializerSyntax initializer)
|
||||
{
|
||||
ITypeSymbol initializerType;
|
||||
var initializerInfo = Context.GetSymbolInfo(initializer);
|
||||
|
||||
switch (initializer.Kind())
|
||||
{
|
||||
var baseType = Symbol.ContainingType.BaseType;
|
||||
if (baseType is null)
|
||||
{
|
||||
if (Symbol.ContainingType.SpecialType != SpecialType.System_Object)
|
||||
{
|
||||
Context.ModelError(Symbol, "Unable to resolve base type in implicit constructor initializer");
|
||||
}
|
||||
case SyntaxKind.BaseConstructorInitializer:
|
||||
initializerType = Symbol.ContainingType.BaseType!;
|
||||
break;
|
||||
case SyntaxKind.ThisConstructorInitializer:
|
||||
initializerType = Symbol.ContainingType;
|
||||
break;
|
||||
default:
|
||||
Context.ModelError(initializer, "Unknown initializer");
|
||||
return;
|
||||
}
|
||||
|
||||
var baseConstructor = baseType.InstanceConstructors.FirstOrDefault(c => c.Arity is 0);
|
||||
|
||||
if (baseConstructor is null)
|
||||
{
|
||||
Context.ModelError(Symbol, "Unable to resolve implicit constructor initializer call");
|
||||
return;
|
||||
}
|
||||
|
||||
var baseConstructorTarget = Create(Context, baseConstructor);
|
||||
var info = new ExpressionInfo(Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(baseType),
|
||||
Location,
|
||||
Kinds.ExprKind.CONSTRUCTOR_INIT,
|
||||
this,
|
||||
-1,
|
||||
isCompilerGenerated: true,
|
||||
null);
|
||||
|
||||
trapFile.expr_call(new Expression(info), baseConstructorTarget);
|
||||
}
|
||||
return;
|
||||
|
||||
ExtractSourceInitializer(trapFile, initializerType, (IMethodSymbol?)initializerInfo.Symbol, initializer.ArgumentList, initializer.ThisOrBaseKeyword.GetLocation());
|
||||
}
|
||||
|
||||
ITypeSymbol initializerType;
|
||||
var symbolInfo = Context.GetSymbolInfo(initializer);
|
||||
|
||||
switch (initializer.Kind())
|
||||
else if (PrimaryBase is PrimaryConstructorBaseTypeSyntax primaryInitializer)
|
||||
{
|
||||
case SyntaxKind.BaseConstructorInitializer:
|
||||
initializerType = Symbol.ContainingType.BaseType!;
|
||||
break;
|
||||
case SyntaxKind.ThisConstructorInitializer:
|
||||
initializerType = Symbol.ContainingType;
|
||||
break;
|
||||
default:
|
||||
Context.ModelError(initializer, "Unknown initializer");
|
||||
return;
|
||||
}
|
||||
var primaryInfo = Context.GetSymbolInfo(primaryInitializer);
|
||||
var primarySymbol = primaryInfo.Symbol;
|
||||
|
||||
ExtractSourceInitializer(trapFile, primarySymbol?.ContainingType, (IMethodSymbol?)primarySymbol, primaryInitializer.ArgumentList, primaryInitializer.GetLocation());
|
||||
}
|
||||
else if (Symbol.MethodKind is MethodKind.Constructor)
|
||||
{
|
||||
var baseType = Symbol.ContainingType.BaseType;
|
||||
if (baseType is null)
|
||||
{
|
||||
if (Symbol.ContainingType.SpecialType != SpecialType.System_Object)
|
||||
{
|
||||
Context.ModelError(Symbol, "Unable to resolve base type in implicit constructor initializer");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var baseConstructor = baseType.InstanceConstructors.FirstOrDefault(c => c.Arity is 0);
|
||||
|
||||
if (baseConstructor is null)
|
||||
{
|
||||
Context.ModelError(Symbol, "Unable to resolve implicit constructor initializer call");
|
||||
return;
|
||||
}
|
||||
|
||||
var baseConstructorTarget = Create(Context, baseConstructor);
|
||||
var info = new ExpressionInfo(Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(baseType),
|
||||
Location,
|
||||
Kinds.ExprKind.CONSTRUCTOR_INIT,
|
||||
this,
|
||||
-1,
|
||||
isCompilerGenerated: true,
|
||||
null);
|
||||
|
||||
trapFile.expr_call(new Expression(info), baseConstructorTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractSourceInitializer(TextWriter trapFile, ITypeSymbol? type, IMethodSymbol? symbol, ArgumentListSyntax arguments, Location location)
|
||||
{
|
||||
var initInfo = new ExpressionInfo(Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(initializerType),
|
||||
Context.CreateLocation(initializer.ThisOrBaseKeyword.GetLocation()),
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
||||
Context.CreateLocation(location),
|
||||
Kinds.ExprKind.CONSTRUCTOR_INIT,
|
||||
this,
|
||||
-1,
|
||||
@@ -103,7 +130,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
var init = new Expression(initInfo);
|
||||
|
||||
var target = Constructor.Create(Context, (IMethodSymbol?)symbolInfo.Symbol);
|
||||
var target = Constructor.Create(Context, symbol);
|
||||
if (target is null)
|
||||
{
|
||||
Context.ModelError(Symbol, "Unable to resolve call");
|
||||
@@ -112,19 +139,27 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
trapFile.expr_call(init, target);
|
||||
|
||||
init.PopulateArguments(trapFile, initializer.ArgumentList, 0);
|
||||
init.PopulateArguments(trapFile, arguments, 0);
|
||||
}
|
||||
|
||||
private ConstructorDeclarationSyntax? Syntax
|
||||
{
|
||||
get
|
||||
{
|
||||
return Symbol.DeclaringSyntaxReferences
|
||||
.Select(r => r.GetSyntax())
|
||||
.OfType<ConstructorDeclarationSyntax>()
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
private ConstructorDeclarationSyntax? OrdinaryConstructorSyntax =>
|
||||
declaringReferenceSyntax
|
||||
.OfType<ConstructorDeclarationSyntax>()
|
||||
.FirstOrDefault();
|
||||
|
||||
private TypeDeclarationSyntax? PrimaryConstructorSyntax =>
|
||||
declaringReferenceSyntax
|
||||
.OfType<TypeDeclarationSyntax>()
|
||||
.FirstOrDefault(t => t is ClassDeclarationSyntax or StructDeclarationSyntax or RecordDeclarationSyntax);
|
||||
|
||||
private PrimaryConstructorBaseTypeSyntax? PrimaryBase =>
|
||||
PrimaryConstructorSyntax?
|
||||
.BaseList?
|
||||
.Types
|
||||
.OfType<PrimaryConstructorBaseTypeSyntax>()
|
||||
.FirstOrDefault();
|
||||
|
||||
private bool IsPrimary => PrimaryConstructorSyntax is not null;
|
||||
|
||||
[return: NotNullIfNotNull(nameof(constructor))]
|
||||
public static new Constructor? Create(Context cx, IMethodSymbol? constructor)
|
||||
@@ -160,19 +195,20 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.Write(";constructor");
|
||||
}
|
||||
|
||||
private ConstructorDeclarationSyntax? GetSyntax() =>
|
||||
Symbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax()).OfType<ConstructorDeclarationSyntax>().FirstOrDefault();
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? FullLocation => ReportingLocation;
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
var syn = GetSyntax();
|
||||
if (syn is not null)
|
||||
if (OrdinaryConstructorSyntax is not null)
|
||||
{
|
||||
return syn.Identifier.GetLocation();
|
||||
return OrdinaryConstructorSyntax.Identifier.GetLocation();
|
||||
}
|
||||
|
||||
if (PrimaryConstructorSyntax is not null)
|
||||
{
|
||||
return PrimaryConstructorSyntax.Identifier.GetLocation();
|
||||
}
|
||||
|
||||
if (Symbol.IsImplicitlyDeclared)
|
||||
|
||||
@@ -54,12 +54,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var block = Block;
|
||||
var expr = ExpressionBody;
|
||||
|
||||
Context.PopulateLater(() => ExtractInitializers(trapFile));
|
||||
|
||||
if (block is not null || expr is not null)
|
||||
{
|
||||
Context.PopulateLater(
|
||||
() =>
|
||||
{
|
||||
ExtractInitializers(trapFile);
|
||||
if (block is not null)
|
||||
Statements.Block.Create(Context, block, this, 0);
|
||||
else
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Entities;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Statements
|
||||
{
|
||||
internal class SyntheticEmptyBlock : Statement<BlockSyntax>
|
||||
{
|
||||
private SyntheticEmptyBlock(Context cx, BlockSyntax block, IStatementParentEntity parent, int child, Location location)
|
||||
: base(cx, block, StmtKind.BLOCK, parent, child, location) { }
|
||||
|
||||
public static SyntheticEmptyBlock Create(Context cx, IStatementParentEntity parent, int child, Location location)
|
||||
{
|
||||
var block = SyntaxFactory.Block();
|
||||
var ret = new SyntheticEmptyBlock(cx, block, parent, child, location);
|
||||
ret.TryPopulate();
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected override void PopulateStatement(TextWriter trapFile) { }
|
||||
}
|
||||
}
|
||||
@@ -416,7 +416,9 @@ class InstanceConstructor extends Constructor {
|
||||
*/
|
||||
class PrimaryConstructor extends Constructor {
|
||||
PrimaryConstructor() {
|
||||
not this.hasBody() and
|
||||
// In the extractor we use the constructor location as the location for the
|
||||
// synthesized empty body of the constructor.
|
||||
this.getLocation() = this.getBody().getLocation() and
|
||||
this.getDeclaringType().fromSource() and
|
||||
this.fromSource()
|
||||
}
|
||||
|
||||
@@ -953,12 +953,8 @@ private module Cached {
|
||||
callCfn = any(Call c | isParamsArg(c, _, _)).getAControlFlowNode()
|
||||
} or
|
||||
TFlowInsensitiveFieldNode(FieldOrProperty f) { f.isFieldLike() } or
|
||||
TInstanceParameterAccessNode(ControlFlow::Node cfn, boolean isPostUpdate) {
|
||||
exists(ParameterAccess pa | cfn = getAPrimaryConstructorParameterCfn(pa) |
|
||||
isPostUpdate = false
|
||||
or
|
||||
pa instanceof ParameterWrite and isPostUpdate = true
|
||||
)
|
||||
TInstanceParameterAccessNode(ControlFlow::Node cfn, Boolean isPostUpdate) {
|
||||
cfn = getAPrimaryConstructorParameterCfn(_)
|
||||
} or
|
||||
TPrimaryConstructorThisAccessNode(Parameter p, Boolean isPostUpdate) {
|
||||
p.getCallable() instanceof PrimaryConstructor
|
||||
|
||||
@@ -25,6 +25,7 @@ constructors.cs:
|
||||
# 23| -1: [TypeMention] object
|
||||
# 23| 1: [Parameter] s
|
||||
# 23| -1: [TypeMention] string
|
||||
# 23| 4: [BlockStmt] {...}
|
||||
# 25| 5: [InstanceConstructor] C1
|
||||
#-----| 2: (Parameters)
|
||||
# 25| 0: [Parameter] o
|
||||
@@ -44,3 +45,7 @@ constructors.cs:
|
||||
# 28| -1: [TypeMention] string
|
||||
# 28| 2: [Parameter] i
|
||||
# 28| -1: [TypeMention] int
|
||||
# 28| 3: [ConstructorInitializer] call to constructor C1
|
||||
# 28| 0: [ParameterAccess] access to parameter o
|
||||
# 28| 1: [ParameterAccess] access to parameter s
|
||||
# 28| 4: [BlockStmt] {...}
|
||||
|
||||
@@ -884,6 +884,7 @@ Record.cs:
|
||||
# 27| -1: [TypeMention] string
|
||||
# 27| 1: [Parameter] LastName
|
||||
# 27| -1: [TypeMention] string
|
||||
# 27| 4: [BlockStmt] {...}
|
||||
# 27| 16: [Property] FirstName
|
||||
# 27| 3: [Getter] get_FirstName
|
||||
# 27| 4: [Setter] set_FirstName
|
||||
@@ -913,6 +914,10 @@ Record.cs:
|
||||
# 29| -1: [TypeMention] string
|
||||
# 29| 2: [Parameter] Subject
|
||||
# 29| -1: [TypeMention] string
|
||||
# 30| 3: [ConstructorInitializer] call to constructor Person1
|
||||
# 30| 0: [ParameterAccess] access to parameter FirstName
|
||||
# 30| 1: [ParameterAccess] access to parameter LastName
|
||||
# 29| 4: [BlockStmt] {...}
|
||||
# 29| 17: [Property] Subject
|
||||
# 29| 3: [Getter] get_Subject
|
||||
# 29| 4: [Setter] set_Subject
|
||||
@@ -937,6 +942,10 @@ Record.cs:
|
||||
# 32| -1: [TypeMention] string
|
||||
# 32| 2: [Parameter] Level
|
||||
# 32| -1: [TypeMention] int
|
||||
# 33| 3: [ConstructorInitializer] call to constructor Person1
|
||||
# 33| 0: [ParameterAccess] access to parameter FirstName
|
||||
# 33| 1: [ParameterAccess] access to parameter LastName
|
||||
# 32| 4: [BlockStmt] {...}
|
||||
# 32| 17: [Property] Level
|
||||
# 32| 3: [Getter] get_Level
|
||||
# 32| 4: [Setter] set_Level
|
||||
@@ -957,6 +966,7 @@ Record.cs:
|
||||
#-----| 2: (Parameters)
|
||||
# 35| 0: [Parameter] Name
|
||||
# 35| -1: [TypeMention] string
|
||||
# 35| 4: [BlockStmt] {...}
|
||||
# 35| 16: [Property] Name
|
||||
# 35| 3: [Getter] get_Name
|
||||
# 35| 4: [Setter] set_Name
|
||||
@@ -981,6 +991,9 @@ Record.cs:
|
||||
#-----| 2: (Parameters)
|
||||
# 41| 0: [Parameter] Name
|
||||
# 41| -1: [TypeMention] string
|
||||
# 41| 3: [ConstructorInitializer] call to constructor Pet
|
||||
# 41| 0: [ParameterAccess] access to parameter Name
|
||||
# 41| 4: [BlockStmt] {...}
|
||||
# 41| 15: [Property] EqualityContract
|
||||
# 41| 3: [Getter] get_EqualityContract
|
||||
# 43| 16: [Method] WagTail
|
||||
@@ -1022,6 +1035,7 @@ Record.cs:
|
||||
#-----| 2: (Parameters)
|
||||
# 54| 0: [Parameter] A
|
||||
# 54| -1: [TypeMention] string
|
||||
# 54| 4: [BlockStmt] {...}
|
||||
# 54| 16: [Property] A
|
||||
# 54| 3: [Getter] get_A
|
||||
# 54| 4: [Setter] set_A
|
||||
@@ -1044,6 +1058,9 @@ Record.cs:
|
||||
# 56| -1: [TypeMention] string
|
||||
# 56| 1: [Parameter] B
|
||||
# 56| -1: [TypeMention] string
|
||||
# 56| 3: [ConstructorInitializer] call to constructor R1
|
||||
# 56| 0: [ParameterAccess] access to parameter A
|
||||
# 56| 4: [BlockStmt] {...}
|
||||
# 56| 17: [Property] B
|
||||
# 56| 3: [Getter] get_B
|
||||
# 56| 4: [Setter] set_B
|
||||
|
||||
@@ -14,7 +14,9 @@ edges
|
||||
| Constructors.cs:33:18:33:19 | this access : C_with_ctor [field s1] : Object | Constructors.cs:33:18:33:19 | access to field s1 | provenance | |
|
||||
| Constructors.cs:41:26:41:26 | o : Object | Constructors.cs:41:38:41:38 | access to parameter o : Object | provenance | |
|
||||
| Constructors.cs:41:38:41:38 | access to parameter o : Object | Constructors.cs:41:32:41:34 | [post] this access : C1 [field Obj] : Object | provenance | |
|
||||
| Constructors.cs:44:28:44:35 | o21param : Object | Constructors.cs:46:23:46:27 | this access : C2 [parameter o21param] : Object | provenance | |
|
||||
| Constructors.cs:44:28:44:35 | o21param : Object | Constructors.cs:46:31:46:38 | access to parameter o21param : Object | provenance | |
|
||||
| Constructors.cs:46:23:46:27 | this access : C2 [parameter o21param] : Object | Constructors.cs:46:31:46:38 | access to parameter o21param : Object | provenance | |
|
||||
| Constructors.cs:46:31:46:38 | access to parameter o21param : Object | Constructors.cs:46:23:46:27 | [post] this access : C2 [field Obj21] : Object | provenance | |
|
||||
| Constructors.cs:48:32:48:39 | this : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | access to parameter o22param : Object | provenance | |
|
||||
| Constructors.cs:50:32:50:36 | this : C2 [field Obj21] : Object | Constructors.cs:50:32:50:36 | this access : C2 [field Obj21] : Object | provenance | |
|
||||
@@ -55,6 +57,13 @@ edges
|
||||
| Constructors.cs:100:25:100:29 | access to local variable taint : Object | Constructors.cs:100:9:100:10 | [post] access to local variable c2 : C2 [parameter o22param] : Object | provenance | |
|
||||
| Constructors.cs:101:14:101:15 | access to local variable c2 : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | this : C2 [parameter o22param] : Object | provenance | |
|
||||
| Constructors.cs:101:14:101:15 | access to local variable c2 : C2 [parameter o22param] : Object | Constructors.cs:101:14:101:21 | access to property Obj22 | provenance | |
|
||||
| Constructors.cs:106:32:106:39 | this : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | access to parameter o31param : Object | provenance | |
|
||||
| Constructors.cs:111:19:111:35 | call to method Source<Object> : Object | Constructors.cs:112:25:112:27 | access to local variable o31 : Object | provenance | |
|
||||
| Constructors.cs:112:18:112:28 | object creation of type C3 : C3 [parameter o31param] : Object | Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | provenance | |
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | Constructors.cs:104:28:104:35 | o31param : Object | provenance | |
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | Constructors.cs:112:18:112:28 | object creation of type C3 : C3 [parameter o31param] : Object | provenance | |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | this : C3 [parameter o31param] : Object | provenance | |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | Constructors.cs:113:14:113:21 | access to property Obj31 | provenance | |
|
||||
nodes
|
||||
| Constructors.cs:5:24:5:25 | [post] this access : C_no_ctor [field s1] : Object | semmle.label | [post] this access : C_no_ctor [field s1] : Object |
|
||||
| Constructors.cs:5:29:5:45 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
|
||||
@@ -76,6 +85,7 @@ nodes
|
||||
| Constructors.cs:44:28:44:35 | o21param : Object | semmle.label | o21param : Object |
|
||||
| Constructors.cs:44:45:44:52 | o22param : Object | semmle.label | o22param : Object |
|
||||
| Constructors.cs:46:23:46:27 | [post] this access : C2 [field Obj21] : Object | semmle.label | [post] this access : C2 [field Obj21] : Object |
|
||||
| Constructors.cs:46:23:46:27 | this access : C2 [parameter o21param] : Object | semmle.label | this access : C2 [parameter o21param] : Object |
|
||||
| Constructors.cs:46:31:46:38 | access to parameter o21param : Object | semmle.label | access to parameter o21param : Object |
|
||||
| Constructors.cs:48:32:48:39 | access to parameter o22param : Object | semmle.label | access to parameter o22param : Object |
|
||||
| Constructors.cs:48:32:48:39 | this : C2 [parameter o22param] : Object | semmle.label | this : C2 [parameter o22param] : Object |
|
||||
@@ -116,6 +126,14 @@ nodes
|
||||
| Constructors.cs:100:25:100:29 | access to local variable taint : Object | semmle.label | access to local variable taint : Object |
|
||||
| Constructors.cs:101:14:101:15 | access to local variable c2 : C2 [parameter o22param] : Object | semmle.label | access to local variable c2 : C2 [parameter o22param] : Object |
|
||||
| Constructors.cs:101:14:101:21 | access to property Obj22 | semmle.label | access to property Obj22 |
|
||||
| Constructors.cs:104:28:104:35 | o31param : Object | semmle.label | o31param : Object |
|
||||
| Constructors.cs:106:32:106:39 | access to parameter o31param : Object | semmle.label | access to parameter o31param : Object |
|
||||
| Constructors.cs:106:32:106:39 | this : C3 [parameter o31param] : Object | semmle.label | this : C3 [parameter o31param] : Object |
|
||||
| Constructors.cs:111:19:111:35 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
|
||||
| Constructors.cs:112:18:112:28 | object creation of type C3 : C3 [parameter o31param] : Object | semmle.label | object creation of type C3 : C3 [parameter o31param] : Object |
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | semmle.label | access to local variable o31 : Object |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | semmle.label | access to local variable c3 : C3 [parameter o31param] : Object |
|
||||
| Constructors.cs:113:14:113:21 | access to property Obj31 | semmle.label | access to property Obj31 |
|
||||
subpaths
|
||||
| Constructors.cs:64:37:64:37 | access to parameter o : Object | Constructors.cs:57:54:57:55 | o2 : Object | Constructors.cs:59:13:59:19 | SSA def(o1) : Object | Constructors.cs:64:27:64:34 | SSA def(o22param) : Object |
|
||||
| Constructors.cs:71:25:71:25 | access to local variable o : Object | Constructors.cs:41:26:41:26 | o : Object | Constructors.cs:41:32:41:34 | [post] this access : C1 [field Obj] : Object | Constructors.cs:71:18:71:26 | object creation of type C1 : C1 [field Obj] : Object |
|
||||
@@ -127,6 +145,8 @@ subpaths
|
||||
| Constructors.cs:93:14:93:15 | access to local variable c2 : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | this : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | access to parameter o22param : Object | Constructors.cs:93:14:93:21 | access to property Obj22 |
|
||||
| Constructors.cs:100:25:100:29 | access to local variable taint : Object | Constructors.cs:62:41:62:41 | o : Object | Constructors.cs:64:27:64:34 | SSA def(o22param) : Object | Constructors.cs:100:9:100:10 | [post] access to local variable c2 : C2 [parameter o22param] : Object |
|
||||
| Constructors.cs:101:14:101:15 | access to local variable c2 : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | this : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | access to parameter o22param : Object | Constructors.cs:101:14:101:21 | access to property Obj22 |
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | Constructors.cs:104:28:104:35 | o31param : Object | Constructors.cs:104:28:104:35 | o31param : Object | Constructors.cs:112:18:112:28 | object creation of type C3 : C3 [parameter o31param] : Object |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | this : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | access to parameter o31param : Object | Constructors.cs:113:14:113:21 | access to property Obj31 |
|
||||
#select
|
||||
| Constructors.cs:15:18:15:19 | access to field s1 | Constructors.cs:5:29:5:45 | call to method Source<Object> : Object | Constructors.cs:15:18:15:19 | access to field s1 | $@ | Constructors.cs:5:29:5:45 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:33:18:33:19 | access to field s1 | Constructors.cs:21:29:21:45 | call to method Source<Object> : Object | Constructors.cs:33:18:33:19 | access to field s1 | $@ | Constructors.cs:21:29:21:45 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
@@ -136,3 +156,4 @@ subpaths
|
||||
| Constructors.cs:82:14:82:21 | access to property Obj23 | Constructors.cs:77:19:77:35 | call to method Source<Object> : Object | Constructors.cs:82:14:82:21 | access to property Obj23 | $@ | Constructors.cs:77:19:77:35 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:93:14:93:21 | access to property Obj22 | Constructors.cs:91:21:91:37 | call to method Source<Object> : Object | Constructors.cs:93:14:93:21 | access to property Obj22 | $@ | Constructors.cs:91:21:91:37 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:101:14:101:21 | access to property Obj22 | Constructors.cs:99:21:99:37 | call to method Source<Object> : Object | Constructors.cs:101:14:101:21 | access to property Obj22 | $@ | Constructors.cs:99:21:99:37 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:113:14:113:21 | access to property Obj31 | Constructors.cs:111:19:111:35 | call to method Source<Object> : Object | Constructors.cs:113:14:113:21 | access to property Obj31 | $@ | Constructors.cs:111:19:111:35 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
|
||||
@@ -101,6 +101,18 @@ public class Constructors
|
||||
Sink(c2.Obj22); // $ hasValueFlow=5
|
||||
}
|
||||
|
||||
public class C3(object o31param)
|
||||
{
|
||||
public object Obj31 => o31param;
|
||||
}
|
||||
|
||||
public void M5()
|
||||
{
|
||||
var o31 = Source<object>(6);
|
||||
var c3 = new C3(o31);
|
||||
Sink(c3.Obj31); // $ hasValueFlow=6
|
||||
}
|
||||
|
||||
public static void Sink(object o) { }
|
||||
|
||||
public static T Source<T>(object source) => throw null;
|
||||
|
||||
@@ -135,6 +135,9 @@
|
||||
| Tuples.cs:87:27:87:27 | SSA def(q) | Tuples.cs:91:18:91:18 | access to local variable q |
|
||||
| Tuples.cs:87:30:87:30 | SSA def(r) | Tuples.cs:90:18:90:18 | access to local variable r |
|
||||
| Tuples.cs:91:18:91:18 | access to local variable q | Tuples.cs:91:18:91:18 | (...) ... |
|
||||
| Tuples.cs:95:12:95:13 | this | Tuples.cs:95:22:95:22 | this |
|
||||
| Tuples.cs:95:22:95:22 | [post] this | Tuples.cs:95:29:95:29 | this |
|
||||
| Tuples.cs:95:22:95:22 | this | Tuples.cs:95:29:95:29 | this |
|
||||
| Tuples.cs:99:13:99:33 | SSA def(o) | Tuples.cs:100:24:100:24 | access to local variable o |
|
||||
| Tuples.cs:99:17:99:33 | call to method Source<String> | Tuples.cs:99:13:99:33 | SSA def(o) |
|
||||
| Tuples.cs:99:32:99:32 | 9 | Tuples.cs:99:32:99:32 | (...) ... |
|
||||
|
||||
@@ -369,6 +369,7 @@ Tuples.cs:
|
||||
# 95| -1: [TypeMention] string
|
||||
# 95| 1: [Parameter] j
|
||||
# 95| -1: [TypeMention] int
|
||||
# 95| 4: [BlockStmt] {...}
|
||||
# 95| 16: [Property] i
|
||||
# 95| 3: [Getter] get_i
|
||||
# 95| 4: [Setter] set_i
|
||||
|
||||
@@ -6,3 +6,5 @@
|
||||
| expressions.cs:271:16:271:24 | IntVector | expressions.cs:271:16:271:24 | call to constructor Object | file://:0:0:0:0 | Object |
|
||||
| expressions.cs:311:16:311:20 | Digit | expressions.cs:311:16:311:20 | call to constructor ValueType | file://:0:0:0:0 | ValueType |
|
||||
| expressions.cs:481:20:481:22 | Num | expressions.cs:481:20:481:22 | call to constructor Object | file://:0:0:0:0 | Object |
|
||||
| expressions.cs:518:11:518:17 | ClassC1 | expressions.cs:518:11:518:17 | call to constructor Object | file://:0:0:0:0 | Object |
|
||||
| expressions.cs:520:11:520:17 | ClassC2 | expressions.cs:520:33:520:44 | call to constructor ClassC1 | expressions.cs:518:11:518:17 | ClassC1 |
|
||||
|
||||
@@ -2406,3 +2406,19 @@ expressions.cs:
|
||||
# 512| 0: [IntLiteral] 10
|
||||
# 515| 5: [Field] myInlineArrayElements
|
||||
# 515| -1: [TypeMention] int
|
||||
# 518| 22: [Class] ClassC1
|
||||
# 518| 4: [InstanceConstructor,PrimaryConstructor] ClassC1
|
||||
#-----| 2: (Parameters)
|
||||
# 518| 0: [Parameter] oc1
|
||||
# 518| -1: [TypeMention] object
|
||||
# 518| 4: [BlockStmt] {...}
|
||||
# 520| 23: [Class] ClassC2
|
||||
#-----| 3: (Base types)
|
||||
# 520| 0: [TypeMention] ClassC1
|
||||
# 520| 4: [InstanceConstructor,PrimaryConstructor] ClassC2
|
||||
#-----| 2: (Parameters)
|
||||
# 520| 0: [Parameter] oc2
|
||||
# 520| -1: [TypeMention] object
|
||||
# 520| 3: [ConstructorInitializer] call to constructor ClassC1
|
||||
# 520| 0: [ParameterAccess] access to parameter oc2
|
||||
# 520| 4: [BlockStmt] {...}
|
||||
|
||||
@@ -514,4 +514,8 @@ namespace Expressions
|
||||
{
|
||||
private int myInlineArrayElements;
|
||||
}
|
||||
|
||||
class ClassC1(object oc1) { }
|
||||
|
||||
class ClassC2(object oc2) : ClassC1(oc2) { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user