mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge branch 'main' into add-using-expired-stack-address-query
This commit is contained in:
2096
cpp/downgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/old.dbscheme
Normal file
2096
cpp/downgrades/bb0f279f2acd793105a347d589b5afc8715d94c4/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Add relation for tracking variables from structured binding declarations
|
||||
compatibility: full
|
||||
is_structured_binding.rel: delete
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a `isStructuredBinding` predicate to the `Variable` class which holds when the variable is declared as part of a structured binding declaration.
|
||||
@@ -169,6 +169,12 @@ class Variable extends Declaration, @variable {
|
||||
variable_instantiation(underlyingElement(this), unresolveElement(v))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this variable is declated as part of a structured binding
|
||||
* declaration. For example, `x` in `auto [x, y] = ...`.
|
||||
*/
|
||||
predicate isStructuredBinding() { is_structured_binding(underlyingElement(this)) }
|
||||
|
||||
/**
|
||||
* Holds if this is a compiler-generated variable. For example, a
|
||||
* [range-based for loop](http://en.cppreference.com/w/cpp/language/range-for)
|
||||
|
||||
@@ -446,6 +446,7 @@ var_decl_specifiers(
|
||||
int id: @var_decl ref,
|
||||
string name: string ref
|
||||
)
|
||||
is_structured_binding(unique int id: @variable ref);
|
||||
|
||||
type_decls(
|
||||
unique int id: @type_decl,
|
||||
|
||||
@@ -14877,6 +14877,17 @@
|
||||
</dependencies>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>is_structured_binding</name>
|
||||
<cardinality>10</cardinality>
|
||||
<columnsizes>
|
||||
<e>
|
||||
<k>id</k>
|
||||
<v>10</v>
|
||||
</e>
|
||||
</columnsizes>
|
||||
<dependencies/>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>type_decls</name>
|
||||
<cardinality>1316547</cardinality>
|
||||
<columnsizes>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add relation for tracking variables from structured binding declarations
|
||||
compatibility: backwards
|
||||
@@ -18,7 +18,6 @@ where
|
||||
not lv1.isCompilerGenerated() and
|
||||
not lv2.isCompilerGenerated() and
|
||||
not lv1.getParentScope().(BlockStmt).isInMacroExpansion() and
|
||||
not lv2.getParentScope().(BlockStmt).isInMacroExpansion() and
|
||||
not lv1.getName() = "(unnamed local variable)"
|
||||
not lv2.getParentScope().(BlockStmt).isInMacroExpansion()
|
||||
select lv1, "Variable " + lv1.getName() + " hides another variable of the same name (on $@).", lv2,
|
||||
"line " + lv2.getLocation().getStartLine().toString()
|
||||
|
||||
@@ -11390,6 +11390,872 @@ ir.cpp:
|
||||
# 1458| Value = [Literal] 3
|
||||
# 1458| ValueCategory = prvalue
|
||||
# 1459| getStmt(1): [ReturnStmt] return ...
|
||||
# 1462| [TopLevelFunction] void array_structured_binding()
|
||||
# 1462| <params>:
|
||||
# 1462| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1463| getStmt(0): [DeclStmt] declaration
|
||||
# 1463| getDeclarationEntry(0): [VariableDeclarationEntry] definition of xs
|
||||
# 1463| Type = [ArrayType] int[2]
|
||||
# 1463| getVariable().getInitializer(): [Initializer] initializer for xs
|
||||
# 1463| getExpr(): [ArrayAggregateLiteral] {...}
|
||||
# 1463| Type = [ArrayType] int[2]
|
||||
# 1463| ValueCategory = prvalue
|
||||
# 1463| getElementExpr(0): [Literal] 1
|
||||
# 1463| Type = [IntType] int
|
||||
# 1463| Value = [Literal] 1
|
||||
# 1463| ValueCategory = prvalue
|
||||
# 1463| getElementExpr(1): [Literal] 2
|
||||
# 1463| Type = [IntType] int
|
||||
# 1463| Value = [Literal] 2
|
||||
# 1463| ValueCategory = prvalue
|
||||
# 1465| getStmt(1): [BlockStmt] { ... }
|
||||
# 1466| getStmt(0): [DeclStmt] declaration
|
||||
# 1466| getDeclarationEntry(0): (no string representation)
|
||||
# 1466| Type = [LValueReferenceType] int(&)[2]
|
||||
# 1466| getVariable().getInitializer(): [Initializer] initializer for (unnamed local variable)
|
||||
# 1466| getExpr(): [VariableAccess] xs
|
||||
# 1466| Type = [ArrayType] int[2]
|
||||
# 1466| ValueCategory = lvalue
|
||||
# 1466| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1466| Type = [LValueReferenceType] int(&)[2]
|
||||
# 1466| ValueCategory = prvalue
|
||||
# 1466| getDeclarationEntry(1): [VariableDeclarationEntry] definition of x0
|
||||
# 1466| Type = [IntType] int
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for x0
|
||||
#-----| getExpr(): [ArrayExpr] access to array
|
||||
#-----| Type = [IntType] int
|
||||
#-----| ValueCategory = lvalue
|
||||
#-----| getArrayBase(): [VariableAccess] (unnamed local variable)
|
||||
#-----| Type = [LValueReferenceType] int(&)[2]
|
||||
#-----| ValueCategory = prvalue(load)
|
||||
#-----| getArrayOffset(): [Literal] 0
|
||||
#-----| Type = [LongType] unsigned long
|
||||
#-----| Value = [Literal] 0
|
||||
#-----| ValueCategory = prvalue
|
||||
#-----| getArrayBase().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
#-----| Type = [IntPointerType] int *
|
||||
#-----| ValueCategory = prvalue
|
||||
#-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
#-----| Type = [ArrayType] int[2]
|
||||
#-----| ValueCategory = lvalue
|
||||
# 1466| getDeclarationEntry(2): [VariableDeclarationEntry] definition of x1
|
||||
# 1466| Type = [IntType] int
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for x1
|
||||
#-----| getExpr(): [ArrayExpr] access to array
|
||||
#-----| Type = [IntType] int
|
||||
#-----| ValueCategory = lvalue
|
||||
#-----| getArrayBase(): [VariableAccess] (unnamed local variable)
|
||||
#-----| Type = [LValueReferenceType] int(&)[2]
|
||||
#-----| ValueCategory = prvalue(load)
|
||||
#-----| getArrayOffset(): [Literal] 1
|
||||
#-----| Type = [LongType] unsigned long
|
||||
#-----| Value = [Literal] 1
|
||||
#-----| ValueCategory = prvalue
|
||||
#-----| getArrayBase().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
#-----| Type = [IntPointerType] int *
|
||||
#-----| ValueCategory = prvalue
|
||||
#-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
#-----| Type = [ArrayType] int[2]
|
||||
#-----| ValueCategory = lvalue
|
||||
# 1467| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 1467| getExpr(): [AssignExpr] ... = ...
|
||||
# 1467| Type = [IntType] int
|
||||
# 1467| ValueCategory = lvalue
|
||||
# 1467| getLValue(): [VariableAccess] x1
|
||||
# 1467| Type = [IntType] int
|
||||
# 1467| ValueCategory = lvalue
|
||||
# 1467| getRValue(): [Literal] 3
|
||||
# 1467| Type = [IntType] int
|
||||
# 1467| Value = [Literal] 3
|
||||
# 1467| ValueCategory = prvalue
|
||||
# 1468| getStmt(2): [DeclStmt] declaration
|
||||
# 1468| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rx1
|
||||
# 1468| Type = [LValueReferenceType] int &
|
||||
# 1468| getVariable().getInitializer(): [Initializer] initializer for rx1
|
||||
# 1468| getExpr(): [VariableAccess] x1
|
||||
# 1468| Type = [IntType] int
|
||||
# 1468| ValueCategory = lvalue
|
||||
# 1468| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1468| Type = [LValueReferenceType] int &
|
||||
# 1468| ValueCategory = prvalue
|
||||
# 1469| getStmt(3): [DeclStmt] declaration
|
||||
# 1469| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 1469| Type = [IntType] int
|
||||
# 1469| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 1469| getExpr(): [VariableAccess] x1
|
||||
# 1469| Type = [IntType] int
|
||||
# 1469| ValueCategory = prvalue(load)
|
||||
# 1472| getStmt(2): [BlockStmt] { ... }
|
||||
# 1473| getStmt(0): [DeclStmt] declaration
|
||||
# 1473| getDeclarationEntry(0): [VariableDeclarationEntry] definition of unnamed_local_variable
|
||||
# 1473| Type = [LValueReferenceType] int(&)[2]
|
||||
# 1473| getVariable().getInitializer(): [Initializer] initializer for unnamed_local_variable
|
||||
# 1473| getExpr(): [VariableAccess] xs
|
||||
# 1473| Type = [ArrayType] int[2]
|
||||
# 1473| ValueCategory = lvalue
|
||||
# 1473| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1473| Type = [LValueReferenceType] int(&)[2]
|
||||
# 1473| ValueCategory = prvalue
|
||||
# 1474| getStmt(1): [DeclStmt] declaration
|
||||
# 1474| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x0
|
||||
# 1474| Type = [LValueReferenceType] int &
|
||||
# 1474| getVariable().getInitializer(): [Initializer] initializer for x0
|
||||
# 1474| getExpr(): [ArrayExpr] access to array
|
||||
# 1474| Type = [IntType] int
|
||||
# 1474| ValueCategory = lvalue
|
||||
# 1474| getArrayBase(): [VariableAccess] xs
|
||||
# 1474| Type = [ArrayType] int[2]
|
||||
# 1474| ValueCategory = lvalue
|
||||
# 1474| getArrayOffset(): [Literal] 0
|
||||
# 1474| Type = [IntType] int
|
||||
# 1474| Value = [Literal] 0
|
||||
# 1474| ValueCategory = prvalue
|
||||
# 1474| getArrayBase().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 1474| Type = [IntPointerType] int *
|
||||
# 1474| ValueCategory = prvalue
|
||||
# 1474| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1474| Type = [LValueReferenceType] int &
|
||||
# 1474| ValueCategory = prvalue
|
||||
# 1475| getStmt(2): [DeclStmt] declaration
|
||||
# 1475| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x1
|
||||
# 1475| Type = [LValueReferenceType] int &
|
||||
# 1475| getVariable().getInitializer(): [Initializer] initializer for x1
|
||||
# 1475| getExpr(): [ArrayExpr] access to array
|
||||
# 1475| Type = [IntType] int
|
||||
# 1475| ValueCategory = lvalue
|
||||
# 1475| getArrayBase(): [VariableAccess] xs
|
||||
# 1475| Type = [ArrayType] int[2]
|
||||
# 1475| ValueCategory = lvalue
|
||||
# 1475| getArrayOffset(): [Literal] 1
|
||||
# 1475| Type = [IntType] int
|
||||
# 1475| Value = [Literal] 1
|
||||
# 1475| ValueCategory = prvalue
|
||||
# 1475| getArrayBase().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 1475| Type = [IntPointerType] int *
|
||||
# 1475| ValueCategory = prvalue
|
||||
# 1475| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1475| Type = [LValueReferenceType] int &
|
||||
# 1475| ValueCategory = prvalue
|
||||
# 1476| getStmt(3): [ExprStmt] ExprStmt
|
||||
# 1476| getExpr(): [AssignExpr] ... = ...
|
||||
# 1476| Type = [IntType] int
|
||||
# 1476| ValueCategory = lvalue
|
||||
# 1476| getLValue(): [VariableAccess] x1
|
||||
# 1476| Type = [LValueReferenceType] int &
|
||||
# 1476| ValueCategory = prvalue(load)
|
||||
# 1476| getRValue(): [Literal] 3
|
||||
# 1476| Type = [IntType] int
|
||||
# 1476| Value = [Literal] 3
|
||||
# 1476| ValueCategory = prvalue
|
||||
# 1476| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1476| Type = [IntType] int
|
||||
# 1476| ValueCategory = lvalue
|
||||
# 1477| getStmt(4): [DeclStmt] declaration
|
||||
# 1477| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rx1
|
||||
# 1477| Type = [LValueReferenceType] int &
|
||||
# 1477| getVariable().getInitializer(): [Initializer] initializer for rx1
|
||||
# 1477| getExpr(): [VariableAccess] x1
|
||||
# 1477| Type = [LValueReferenceType] int &
|
||||
# 1477| ValueCategory = prvalue(load)
|
||||
# 1477| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1477| Type = [LValueReferenceType] int &
|
||||
# 1477| ValueCategory = prvalue
|
||||
# 1477| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1477| Type = [IntType] int
|
||||
# 1477| ValueCategory = lvalue
|
||||
# 1478| getStmt(5): [DeclStmt] declaration
|
||||
# 1478| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 1478| Type = [IntType] int
|
||||
# 1478| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 1478| getExpr(): [VariableAccess] x1
|
||||
# 1478| Type = [LValueReferenceType] int &
|
||||
# 1478| ValueCategory = prvalue(load)
|
||||
# 1478| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1478| Type = [IntType] int
|
||||
# 1478| ValueCategory = prvalue(load)
|
||||
# 1480| getStmt(3): [ReturnStmt] return ...
|
||||
# 1482| [CopyAssignmentOperator] StructuredBindingDataMemberStruct& StructuredBindingDataMemberStruct::operator=(StructuredBindingDataMemberStruct const&)
|
||||
# 1482| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const StructuredBindingDataMemberStruct &
|
||||
# 1482| [Constructor] void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct()
|
||||
# 1482| <params>:
|
||||
# 1482| <initializations>:
|
||||
# 1482| getInitializer(0): [ConstructorFieldInit] constructor init of field i
|
||||
# 1482| Type = [IntType] int
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getInitializer(1): [ConstructorFieldInit] constructor init of field d
|
||||
# 1482| Type = [DoubleType] double
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getInitializer(2): [ConstructorFieldInit] constructor init of field r
|
||||
# 1482| Type = [LValueReferenceType] int &
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1482| getStmt(0): [ReturnStmt] return ...
|
||||
# 1482| [CopyConstructor] void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct(StructuredBindingDataMemberStruct const&)
|
||||
# 1482| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const StructuredBindingDataMemberStruct &
|
||||
# 1482| <initializations>:
|
||||
# 1482| getInitializer(0): [ConstructorFieldInit] constructor init of field i
|
||||
# 1482| Type = [IntType] int
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getExpr(): [Literal] Unknown literal
|
||||
# 1482| Type = [IntType] int
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getInitializer(1): [ConstructorFieldInit] constructor init of field d
|
||||
# 1482| Type = [DoubleType] double
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getExpr(): [Literal] Unknown literal
|
||||
# 1482| Type = [DoubleType] double
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getInitializer(2): [ConstructorFieldInit] constructor init of field b
|
||||
# 1482| Type = [IntType] unsigned int
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getExpr(): [Literal] Unknown literal
|
||||
# 1482| Type = [IntType] unsigned int
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getInitializer(3): [ConstructorFieldInit] constructor init of field r
|
||||
# 1482| Type = [LValueReferenceType] int &
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getExpr(): [Literal] Unknown literal
|
||||
# 1482| Type = [LValueReferenceType] int &
|
||||
# 1482| ValueCategory = prvalue
|
||||
# 1482| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1482| getStmt(0): [ReturnStmt] return ...
|
||||
# 1482| [MoveConstructor] void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct(StructuredBindingDataMemberStruct&&)
|
||||
# 1482| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] StructuredBindingDataMemberStruct &&
|
||||
# 1489| [TopLevelFunction] void data_member_structured_binding()
|
||||
# 1489| <params>:
|
||||
# 1489| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1490| getStmt(0): [DeclStmt] declaration
|
||||
# 1490| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 1490| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1490| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 1490| getExpr(): [ConstructorCall] call to StructuredBindingDataMemberStruct
|
||||
# 1490| Type = [VoidType] void
|
||||
# 1490| ValueCategory = prvalue
|
||||
# 1492| getStmt(1): [BlockStmt] { ... }
|
||||
# 1493| getStmt(0): [DeclStmt] declaration
|
||||
# 1493| getDeclarationEntry(0): (no string representation)
|
||||
# 1493| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1493| getVariable().getInitializer(): [Initializer] initializer for (unnamed local variable)
|
||||
# 1493| getExpr(): [VariableAccess] s
|
||||
# 1493| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1493| ValueCategory = prvalue(load)
|
||||
# 1493| getDeclarationEntry(1): [VariableDeclarationEntry] definition of i
|
||||
# 1493| Type = [IntType] int
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for i
|
||||
# 1493| getExpr(): [ValueFieldAccess] i
|
||||
# 1493| Type = [IntType] int
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1493| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getDeclarationEntry(2): [VariableDeclarationEntry] definition of d
|
||||
# 1493| Type = [DoubleType] double
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for d
|
||||
# 1493| getExpr(): [ValueFieldAccess] d
|
||||
# 1493| Type = [DoubleType] double
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1493| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getDeclarationEntry(3): [VariableDeclarationEntry] definition of b
|
||||
# 1493| Type = [IntType] unsigned int
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for b
|
||||
# 1493| getExpr(): [ValueFieldAccess] b
|
||||
# 1493| Type = [IntType] unsigned int
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1493| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getDeclarationEntry(4): [VariableDeclarationEntry] definition of r
|
||||
# 1493| Type = [IntType] int
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for r
|
||||
# 1493| getExpr(): [ValueFieldAccess] r
|
||||
# 1493| Type = [LValueReferenceType] int &
|
||||
# 1493| ValueCategory = prvalue(load)
|
||||
# 1493| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1493| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1493| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1493| Type = [IntType] int
|
||||
# 1493| ValueCategory = lvalue
|
||||
# 1494| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 1494| getExpr(): [AssignExpr] ... = ...
|
||||
# 1494| Type = [DoubleType] double
|
||||
# 1494| ValueCategory = lvalue
|
||||
# 1494| getLValue(): [VariableAccess] d
|
||||
# 1494| Type = [DoubleType] double
|
||||
# 1494| ValueCategory = lvalue
|
||||
# 1494| getRValue(): [Literal] 4.0
|
||||
# 1494| Type = [DoubleType] double
|
||||
# 1494| Value = [Literal] 4.0
|
||||
# 1494| ValueCategory = prvalue
|
||||
# 1495| getStmt(2): [DeclStmt] declaration
|
||||
# 1495| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rd
|
||||
# 1495| Type = [LValueReferenceType] double &
|
||||
# 1495| getVariable().getInitializer(): [Initializer] initializer for rd
|
||||
# 1495| getExpr(): [VariableAccess] d
|
||||
# 1495| Type = [DoubleType] double
|
||||
# 1495| ValueCategory = lvalue
|
||||
# 1495| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1495| Type = [LValueReferenceType] double &
|
||||
# 1495| ValueCategory = prvalue
|
||||
# 1496| getStmt(3): [DeclStmt] declaration
|
||||
# 1496| getDeclarationEntry(0): [VariableDeclarationEntry] definition of v
|
||||
# 1496| Type = [IntType] int
|
||||
# 1496| getVariable().getInitializer(): [Initializer] initializer for v
|
||||
# 1496| getExpr(): [VariableAccess] i
|
||||
# 1496| Type = [IntType] int
|
||||
# 1496| ValueCategory = prvalue(load)
|
||||
# 1497| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 1497| getExpr(): [AssignExpr] ... = ...
|
||||
# 1497| Type = [IntType] int
|
||||
# 1497| ValueCategory = lvalue
|
||||
# 1497| getLValue(): [VariableAccess] r
|
||||
# 1497| Type = [IntType] int
|
||||
# 1497| ValueCategory = lvalue
|
||||
# 1497| getRValue(): [Literal] 5
|
||||
# 1497| Type = [IntType] int
|
||||
# 1497| Value = [Literal] 5
|
||||
# 1497| ValueCategory = prvalue
|
||||
# 1498| getStmt(5): [DeclStmt] declaration
|
||||
# 1498| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rr
|
||||
# 1498| Type = [LValueReferenceType] int &
|
||||
# 1498| getVariable().getInitializer(): [Initializer] initializer for rr
|
||||
# 1498| getExpr(): [VariableAccess] r
|
||||
# 1498| Type = [IntType] int
|
||||
# 1498| ValueCategory = lvalue
|
||||
# 1498| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1498| Type = [LValueReferenceType] int &
|
||||
# 1498| ValueCategory = prvalue
|
||||
# 1499| getStmt(6): [DeclStmt] declaration
|
||||
# 1499| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
|
||||
# 1499| Type = [IntType] int
|
||||
# 1499| getVariable().getInitializer(): [Initializer] initializer for w
|
||||
# 1499| getExpr(): [VariableAccess] r
|
||||
# 1499| Type = [IntType] int
|
||||
# 1499| ValueCategory = prvalue(load)
|
||||
# 1502| getStmt(2): [BlockStmt] { ... }
|
||||
# 1503| getStmt(0): [DeclStmt] declaration
|
||||
# 1503| getDeclarationEntry(0): [VariableDeclarationEntry] definition of unnamed_local_variable
|
||||
# 1503| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1503| getVariable().getInitializer(): [Initializer] initializer for unnamed_local_variable
|
||||
# 1503| getExpr(): [VariableAccess] s
|
||||
# 1503| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1503| ValueCategory = prvalue(load)
|
||||
# 1504| getStmt(1): [DeclStmt] declaration
|
||||
# 1504| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i
|
||||
# 1504| Type = [LValueReferenceType] int &
|
||||
# 1504| getVariable().getInitializer(): [Initializer] initializer for i
|
||||
# 1504| getExpr(): [ValueFieldAccess] i
|
||||
# 1504| Type = [IntType] int
|
||||
# 1504| ValueCategory = lvalue
|
||||
# 1504| getQualifier(): [VariableAccess] unnamed_local_variable
|
||||
# 1504| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1504| ValueCategory = lvalue
|
||||
# 1504| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1504| Type = [LValueReferenceType] int &
|
||||
# 1504| ValueCategory = prvalue
|
||||
# 1505| getStmt(2): [DeclStmt] declaration
|
||||
# 1505| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
|
||||
# 1505| Type = [LValueReferenceType] double &
|
||||
# 1505| getVariable().getInitializer(): [Initializer] initializer for d
|
||||
# 1505| getExpr(): [ValueFieldAccess] d
|
||||
# 1505| Type = [DoubleType] double
|
||||
# 1505| ValueCategory = lvalue
|
||||
# 1505| getQualifier(): [VariableAccess] unnamed_local_variable
|
||||
# 1505| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1505| ValueCategory = lvalue
|
||||
# 1505| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1505| Type = [LValueReferenceType] double &
|
||||
# 1505| ValueCategory = prvalue
|
||||
# 1507| getStmt(3): [DeclStmt] declaration
|
||||
# 1507| getDeclarationEntry(0): [VariableDeclarationEntry] definition of r
|
||||
# 1507| Type = [LValueReferenceType] int &
|
||||
# 1507| getVariable().getInitializer(): [Initializer] initializer for r
|
||||
# 1507| getExpr(): [ValueFieldAccess] r
|
||||
# 1507| Type = [LValueReferenceType] int &
|
||||
# 1507| ValueCategory = prvalue(load)
|
||||
# 1507| getQualifier(): [VariableAccess] unnamed_local_variable
|
||||
# 1507| Type = [Struct] StructuredBindingDataMemberStruct
|
||||
# 1507| ValueCategory = lvalue
|
||||
# 1507| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1507| Type = [LValueReferenceType] int &
|
||||
# 1507| ValueCategory = prvalue
|
||||
# 1507| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1507| Type = [IntType] int
|
||||
# 1507| ValueCategory = lvalue
|
||||
# 1508| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 1508| getExpr(): [AssignExpr] ... = ...
|
||||
# 1508| Type = [DoubleType] double
|
||||
# 1508| ValueCategory = lvalue
|
||||
# 1508| getLValue(): [VariableAccess] d
|
||||
# 1508| Type = [LValueReferenceType] double &
|
||||
# 1508| ValueCategory = prvalue(load)
|
||||
# 1508| getRValue(): [Literal] 4.0
|
||||
# 1508| Type = [DoubleType] double
|
||||
# 1508| Value = [Literal] 4.0
|
||||
# 1508| ValueCategory = prvalue
|
||||
# 1508| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1508| Type = [DoubleType] double
|
||||
# 1508| ValueCategory = lvalue
|
||||
# 1509| getStmt(5): [DeclStmt] declaration
|
||||
# 1509| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rd
|
||||
# 1509| Type = [LValueReferenceType] double &
|
||||
# 1509| getVariable().getInitializer(): [Initializer] initializer for rd
|
||||
# 1509| getExpr(): [VariableAccess] d
|
||||
# 1509| Type = [LValueReferenceType] double &
|
||||
# 1509| ValueCategory = prvalue(load)
|
||||
# 1509| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1509| Type = [LValueReferenceType] double &
|
||||
# 1509| ValueCategory = prvalue
|
||||
# 1509| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1509| Type = [DoubleType] double
|
||||
# 1509| ValueCategory = lvalue
|
||||
# 1510| getStmt(6): [DeclStmt] declaration
|
||||
# 1510| getDeclarationEntry(0): [VariableDeclarationEntry] definition of v
|
||||
# 1510| Type = [IntType] int
|
||||
# 1510| getVariable().getInitializer(): [Initializer] initializer for v
|
||||
# 1510| getExpr(): [VariableAccess] i
|
||||
# 1510| Type = [LValueReferenceType] int &
|
||||
# 1510| ValueCategory = prvalue(load)
|
||||
# 1510| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1510| Type = [IntType] int
|
||||
# 1510| ValueCategory = prvalue(load)
|
||||
# 1511| getStmt(7): [ExprStmt] ExprStmt
|
||||
# 1511| getExpr(): [AssignExpr] ... = ...
|
||||
# 1511| Type = [IntType] int
|
||||
# 1511| ValueCategory = lvalue
|
||||
# 1511| getLValue(): [VariableAccess] r
|
||||
# 1511| Type = [LValueReferenceType] int &
|
||||
# 1511| ValueCategory = prvalue(load)
|
||||
# 1511| getRValue(): [Literal] 5
|
||||
# 1511| Type = [IntType] int
|
||||
# 1511| Value = [Literal] 5
|
||||
# 1511| ValueCategory = prvalue
|
||||
# 1511| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1511| Type = [IntType] int
|
||||
# 1511| ValueCategory = lvalue
|
||||
# 1512| getStmt(8): [DeclStmt] declaration
|
||||
# 1512| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rr
|
||||
# 1512| Type = [LValueReferenceType] int &
|
||||
# 1512| getVariable().getInitializer(): [Initializer] initializer for rr
|
||||
# 1512| getExpr(): [VariableAccess] r
|
||||
# 1512| Type = [LValueReferenceType] int &
|
||||
# 1512| ValueCategory = prvalue(load)
|
||||
# 1512| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1512| Type = [LValueReferenceType] int &
|
||||
# 1512| ValueCategory = prvalue
|
||||
# 1512| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1512| Type = [IntType] int
|
||||
# 1512| ValueCategory = lvalue
|
||||
# 1513| getStmt(9): [DeclStmt] declaration
|
||||
# 1513| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
|
||||
# 1513| Type = [IntType] int
|
||||
# 1513| getVariable().getInitializer(): [Initializer] initializer for w
|
||||
# 1513| getExpr(): [VariableAccess] r
|
||||
# 1513| Type = [LValueReferenceType] int &
|
||||
# 1513| ValueCategory = prvalue(load)
|
||||
# 1513| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1513| Type = [IntType] int
|
||||
# 1513| ValueCategory = prvalue(load)
|
||||
# 1515| getStmt(3): [ReturnStmt] return ...
|
||||
# 1522| [CopyAssignmentOperator] std::tuple_size<StructuredBindingTuple>& std::tuple_size<StructuredBindingTuple>::operator=(std::tuple_size<StructuredBindingTuple> const&)
|
||||
# 1522| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const tuple_size<StructuredBindingTuple> &
|
||||
# 1522| [MoveAssignmentOperator] std::tuple_size<StructuredBindingTuple>& std::tuple_size<StructuredBindingTuple>::operator=(std::tuple_size<StructuredBindingTuple>&&)
|
||||
# 1522| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] tuple_size<StructuredBindingTuple> &&
|
||||
# 1529| [CopyAssignmentOperator] std::tuple_element<int 0, StructuredBindingTuple>& std::tuple_element<int 0, StructuredBindingTuple>::operator=(std::tuple_element<int 0, StructuredBindingTuple> const&)
|
||||
# 1529| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const tuple_element<0, StructuredBindingTuple> &
|
||||
# 1529| [MoveAssignmentOperator] std::tuple_element<int 0, StructuredBindingTuple>& std::tuple_element<int 0, StructuredBindingTuple>::operator=(std::tuple_element<int 0, StructuredBindingTuple>&&)
|
||||
# 1529| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] tuple_element<0, StructuredBindingTuple> &&
|
||||
# 1533| [CopyAssignmentOperator] std::tuple_element<int 1, StructuredBindingTuple>& std::tuple_element<int 1, StructuredBindingTuple>::operator=(std::tuple_element<int 1, StructuredBindingTuple> const&)
|
||||
# 1533| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const tuple_element<1, StructuredBindingTuple> &
|
||||
# 1533| [MoveAssignmentOperator] std::tuple_element<int 1, StructuredBindingTuple>& std::tuple_element<int 1, StructuredBindingTuple>::operator=(std::tuple_element<int 1, StructuredBindingTuple>&&)
|
||||
# 1533| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] tuple_element<1, StructuredBindingTuple> &&
|
||||
# 1537| [CopyAssignmentOperator] std::tuple_element<int 2, StructuredBindingTuple>& std::tuple_element<int 2, StructuredBindingTuple>::operator=(std::tuple_element<int 2, StructuredBindingTuple> const&)
|
||||
# 1537| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const tuple_element<2, StructuredBindingTuple> &
|
||||
# 1537| [MoveAssignmentOperator] std::tuple_element<int 2, StructuredBindingTuple>& std::tuple_element<int 2, StructuredBindingTuple>::operator=(std::tuple_element<int 2, StructuredBindingTuple>&&)
|
||||
# 1537| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] tuple_element<2, StructuredBindingTuple> &&
|
||||
# 1542| [CopyAssignmentOperator] StructuredBindingTuple& StructuredBindingTuple::operator=(StructuredBindingTuple const&)
|
||||
# 1542| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const StructuredBindingTuple &
|
||||
# 1542| [Constructor] void StructuredBindingTuple::StructuredBindingTuple()
|
||||
# 1542| <params>:
|
||||
# 1542| <initializations>:
|
||||
# 1542| getInitializer(0): [ConstructorFieldInit] constructor init of field i
|
||||
# 1542| Type = [IntType] int
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getInitializer(1): [ConstructorFieldInit] constructor init of field d
|
||||
# 1542| Type = [DoubleType] double
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getInitializer(2): [ConstructorFieldInit] constructor init of field r
|
||||
# 1542| Type = [LValueReferenceType] int &
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1542| getStmt(0): [ReturnStmt] return ...
|
||||
# 1542| [CopyConstructor] void StructuredBindingTuple::StructuredBindingTuple(StructuredBindingTuple const&)
|
||||
# 1542| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const StructuredBindingTuple &
|
||||
# 1542| <initializations>:
|
||||
# 1542| getInitializer(0): [ConstructorFieldInit] constructor init of field i
|
||||
# 1542| Type = [IntType] int
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getExpr(): [Literal] Unknown literal
|
||||
# 1542| Type = [IntType] int
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getInitializer(1): [ConstructorFieldInit] constructor init of field d
|
||||
# 1542| Type = [DoubleType] double
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getExpr(): [Literal] Unknown literal
|
||||
# 1542| Type = [DoubleType] double
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getInitializer(2): [ConstructorFieldInit] constructor init of field r
|
||||
# 1542| Type = [LValueReferenceType] int &
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getExpr(): [Literal] Unknown literal
|
||||
# 1542| Type = [LValueReferenceType] int &
|
||||
# 1542| ValueCategory = prvalue
|
||||
# 1542| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1542| getStmt(0): [ReturnStmt] return ...
|
||||
# 1542| [MoveConstructor] void StructuredBindingTuple::StructuredBindingTuple(StructuredBindingTuple&&)
|
||||
# 1542| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] StructuredBindingTuple &&
|
||||
# 1548| [MemberFunction,TemplateFunction] type& StructuredBindingTuple::get<int i>()
|
||||
# 1548| <params>:
|
||||
# 1552| [FunctionTemplateSpecialization,MemberFunction] std::tuple_element<int 0, StructuredBindingTuple>::type& StructuredBindingTuple::get<int 0>()
|
||||
# 1552| <params>:
|
||||
# 1552| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1552| getStmt(0): [ReturnStmt] return ...
|
||||
# 1552| getExpr(): [PointerFieldAccess] i
|
||||
# 1552| Type = [IntType] int
|
||||
# 1552| ValueCategory = lvalue
|
||||
# 1552| getQualifier(): [ThisExpr] this
|
||||
# 1552| Type = [PointerType] StructuredBindingTuple *
|
||||
# 1552| ValueCategory = prvalue(load)
|
||||
#-----| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
#-----| Type = [LValueReferenceType] int &
|
||||
#-----| ValueCategory = prvalue
|
||||
# 1554| [FunctionTemplateSpecialization,MemberFunction] std::tuple_element<int 1, StructuredBindingTuple>::type& StructuredBindingTuple::get<int 1>()
|
||||
# 1554| <params>:
|
||||
# 1554| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1554| getStmt(0): [ReturnStmt] return ...
|
||||
# 1554| getExpr(): [PointerFieldAccess] d
|
||||
# 1554| Type = [DoubleType] double
|
||||
# 1554| ValueCategory = lvalue
|
||||
# 1554| getQualifier(): [ThisExpr] this
|
||||
# 1554| Type = [PointerType] StructuredBindingTuple *
|
||||
# 1554| ValueCategory = prvalue(load)
|
||||
#-----| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
#-----| Type = [LValueReferenceType] double &
|
||||
#-----| ValueCategory = prvalue
|
||||
# 1556| [FunctionTemplateSpecialization,MemberFunction] std::tuple_element<int 2, StructuredBindingTuple>::type StructuredBindingTuple::get<int 2>()
|
||||
# 1556| <params>:
|
||||
# 1556| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1556| getStmt(0): [ReturnStmt] return ...
|
||||
# 1556| getExpr(): [PointerFieldAccess] r
|
||||
# 1556| Type = [LValueReferenceType] int &
|
||||
# 1556| ValueCategory = prvalue(load)
|
||||
# 1556| getQualifier(): [ThisExpr] this
|
||||
# 1556| Type = [PointerType] StructuredBindingTuple *
|
||||
# 1556| ValueCategory = prvalue(load)
|
||||
# 1556| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1556| Type = [LValueReferenceType] int &
|
||||
# 1556| ValueCategory = prvalue
|
||||
# 1556| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1556| Type = [IntType] int
|
||||
# 1556| ValueCategory = lvalue
|
||||
# 1558| [TopLevelFunction] void tuple_structured_binding()
|
||||
# 1558| <params>:
|
||||
# 1558| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1559| getStmt(0): [DeclStmt] declaration
|
||||
# 1559| getDeclarationEntry(0): [VariableDeclarationEntry] definition of t
|
||||
# 1559| Type = [Struct] StructuredBindingTuple
|
||||
# 1559| getVariable().getInitializer(): [Initializer] initializer for t
|
||||
# 1559| getExpr(): [ConstructorCall] call to StructuredBindingTuple
|
||||
# 1559| Type = [VoidType] void
|
||||
# 1559| ValueCategory = prvalue
|
||||
# 1561| getStmt(1): [BlockStmt] { ... }
|
||||
# 1562| getStmt(0): [DeclStmt] declaration
|
||||
# 1562| getDeclarationEntry(0): (no string representation)
|
||||
# 1562| Type = [Struct] StructuredBindingTuple
|
||||
# 1562| getVariable().getInitializer(): [Initializer] initializer for (unnamed local variable)
|
||||
# 1562| getExpr(): [VariableAccess] t
|
||||
# 1562| Type = [Struct] StructuredBindingTuple
|
||||
# 1562| ValueCategory = prvalue(load)
|
||||
# 1562| getDeclarationEntry(1): [VariableDeclarationEntry] definition of i
|
||||
# 1562| Type = [LValueReferenceType] type &
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for i
|
||||
# 1562| getExpr(): [FunctionCall] call to get
|
||||
# 1562| Type = [LValueReferenceType] type &
|
||||
# 1562| ValueCategory = prvalue
|
||||
# 1562| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1562| Type = [Struct] StructuredBindingTuple
|
||||
# 1562| ValueCategory = xvalue
|
||||
# 1562| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1562| Type = [LValueReferenceType] type &
|
||||
# 1562| ValueCategory = prvalue
|
||||
# 1562| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1562| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1562| ValueCategory = lvalue
|
||||
# 1562| getDeclarationEntry(2): [VariableDeclarationEntry] definition of d
|
||||
# 1562| Type = [LValueReferenceType] type &
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for d
|
||||
# 1562| getExpr(): [FunctionCall] call to get
|
||||
# 1562| Type = [LValueReferenceType] type &
|
||||
# 1562| ValueCategory = prvalue
|
||||
# 1562| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1562| Type = [Struct] StructuredBindingTuple
|
||||
# 1562| ValueCategory = xvalue
|
||||
# 1562| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1562| Type = [LValueReferenceType] type &
|
||||
# 1562| ValueCategory = prvalue
|
||||
# 1562| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1562| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1562| ValueCategory = lvalue
|
||||
# 1562| getDeclarationEntry(3): [VariableDeclarationEntry] definition of r
|
||||
# 1562| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for r
|
||||
# 1562| getExpr(): [FunctionCall] call to get
|
||||
# 1562| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1562| ValueCategory = prvalue
|
||||
# 1562| getQualifier(): [VariableAccess] (unnamed local variable)
|
||||
# 1562| Type = [Struct] StructuredBindingTuple
|
||||
# 1562| ValueCategory = xvalue
|
||||
# 1562| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1562| Type = [LValueReferenceType] int &
|
||||
# 1562| ValueCategory = prvalue
|
||||
# 1562| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1562| Type = [IntType] int
|
||||
# 1562| ValueCategory = lvalue
|
||||
# 1563| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 1563| getExpr(): [AssignExpr] ... = ...
|
||||
# 1563| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1563| ValueCategory = lvalue
|
||||
# 1563| getLValue(): [VariableAccess] d
|
||||
# 1563| Type = [LValueReferenceType] type &
|
||||
# 1563| ValueCategory = prvalue(load)
|
||||
# 1563| getRValue(): [Literal] 4.0
|
||||
# 1563| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1563| Value = [Literal] 4.0
|
||||
# 1563| ValueCategory = prvalue
|
||||
# 1563| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1563| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1563| ValueCategory = lvalue
|
||||
# 1564| getStmt(2): [DeclStmt] declaration
|
||||
# 1564| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rd
|
||||
# 1564| Type = [LValueReferenceType] double &
|
||||
# 1564| getVariable().getInitializer(): [Initializer] initializer for rd
|
||||
# 1564| getExpr(): [VariableAccess] d
|
||||
# 1564| Type = [LValueReferenceType] type &
|
||||
# 1564| ValueCategory = prvalue(load)
|
||||
# 1564| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1564| Type = [LValueReferenceType] type &
|
||||
# 1564| ValueCategory = prvalue
|
||||
# 1564| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1564| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1564| ValueCategory = lvalue
|
||||
# 1565| getStmt(3): [DeclStmt] declaration
|
||||
# 1565| getDeclarationEntry(0): [VariableDeclarationEntry] definition of v
|
||||
# 1565| Type = [IntType] int
|
||||
# 1565| getVariable().getInitializer(): [Initializer] initializer for v
|
||||
# 1565| getExpr(): [VariableAccess] i
|
||||
# 1565| Type = [LValueReferenceType] type &
|
||||
# 1565| ValueCategory = prvalue(load)
|
||||
# 1565| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1565| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1565| ValueCategory = prvalue(load)
|
||||
# 1566| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 1566| getExpr(): [AssignExpr] ... = ...
|
||||
# 1566| Type = [IntType] int
|
||||
# 1566| ValueCategory = lvalue
|
||||
# 1566| getLValue(): [VariableAccess] r
|
||||
# 1566| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1566| ValueCategory = prvalue(load)
|
||||
# 1566| getRValue(): [Literal] 5
|
||||
# 1566| Type = [IntType] int
|
||||
# 1566| Value = [Literal] 5
|
||||
# 1566| ValueCategory = prvalue
|
||||
# 1566| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1566| Type = [IntType] int
|
||||
# 1566| ValueCategory = lvalue
|
||||
# 1567| getStmt(5): [DeclStmt] declaration
|
||||
# 1567| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rr
|
||||
# 1567| Type = [LValueReferenceType] int &
|
||||
# 1567| getVariable().getInitializer(): [Initializer] initializer for rr
|
||||
# 1567| getExpr(): [VariableAccess] r
|
||||
# 1567| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1567| ValueCategory = prvalue(load)
|
||||
# 1567| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1567| Type = [LValueReferenceType] int &
|
||||
# 1567| ValueCategory = prvalue
|
||||
# 1567| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1567| Type = [IntType] int
|
||||
# 1567| ValueCategory = lvalue
|
||||
# 1568| getStmt(6): [DeclStmt] declaration
|
||||
# 1568| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
|
||||
# 1568| Type = [IntType] int
|
||||
# 1568| getVariable().getInitializer(): [Initializer] initializer for w
|
||||
# 1568| getExpr(): [VariableAccess] r
|
||||
# 1568| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1568| ValueCategory = prvalue(load)
|
||||
# 1568| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1568| Type = [IntType] int
|
||||
# 1568| ValueCategory = prvalue(load)
|
||||
# 1571| getStmt(2): [BlockStmt] { ... }
|
||||
# 1572| getStmt(0): [DeclStmt] declaration
|
||||
# 1572| getDeclarationEntry(0): [VariableDeclarationEntry] definition of unnamed_local_variable
|
||||
# 1572| Type = [Struct] StructuredBindingTuple
|
||||
# 1572| getVariable().getInitializer(): [Initializer] initializer for unnamed_local_variable
|
||||
# 1572| getExpr(): [VariableAccess] t
|
||||
# 1572| Type = [Struct] StructuredBindingTuple
|
||||
# 1572| ValueCategory = prvalue(load)
|
||||
# 1573| getStmt(1): [DeclStmt] declaration
|
||||
# 1573| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i
|
||||
# 1573| Type = [LValueReferenceType] type &
|
||||
# 1573| getVariable().getInitializer(): [Initializer] initializer for i
|
||||
# 1573| getExpr(): [FunctionCall] call to get
|
||||
# 1573| Type = [LValueReferenceType] type &
|
||||
# 1573| ValueCategory = prvalue
|
||||
# 1573| getQualifier(): [VariableAccess] unnamed_local_variable
|
||||
# 1573| Type = [Struct] StructuredBindingTuple
|
||||
# 1573| ValueCategory = lvalue
|
||||
# 1573| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1573| Type = [LValueReferenceType] type &
|
||||
# 1573| ValueCategory = prvalue
|
||||
# 1573| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1573| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1573| ValueCategory = lvalue
|
||||
# 1574| getStmt(2): [DeclStmt] declaration
|
||||
# 1574| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
|
||||
# 1574| Type = [LValueReferenceType] type &
|
||||
# 1574| getVariable().getInitializer(): [Initializer] initializer for d
|
||||
# 1574| getExpr(): [FunctionCall] call to get
|
||||
# 1574| Type = [LValueReferenceType] type &
|
||||
# 1574| ValueCategory = prvalue
|
||||
# 1574| getQualifier(): [VariableAccess] unnamed_local_variable
|
||||
# 1574| Type = [Struct] StructuredBindingTuple
|
||||
# 1574| ValueCategory = lvalue
|
||||
# 1574| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1574| Type = [LValueReferenceType] type &
|
||||
# 1574| ValueCategory = prvalue
|
||||
# 1574| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1574| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1574| ValueCategory = lvalue
|
||||
# 1575| getStmt(3): [DeclStmt] declaration
|
||||
# 1575| getDeclarationEntry(0): [VariableDeclarationEntry] definition of r
|
||||
# 1575| Type = [LValueReferenceType] int &
|
||||
# 1575| getVariable().getInitializer(): [Initializer] initializer for r
|
||||
# 1575| getExpr(): [FunctionCall] call to get
|
||||
# 1575| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1575| ValueCategory = prvalue
|
||||
# 1575| getQualifier(): [VariableAccess] unnamed_local_variable
|
||||
# 1575| Type = [Struct] StructuredBindingTuple
|
||||
# 1575| ValueCategory = lvalue
|
||||
# 1575| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1575| Type = [LValueReferenceType] int &
|
||||
# 1575| ValueCategory = prvalue
|
||||
# 1575| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1575| Type = [IntType] int
|
||||
# 1575| ValueCategory = lvalue
|
||||
# 1576| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 1576| getExpr(): [AssignExpr] ... = ...
|
||||
# 1576| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1576| ValueCategory = lvalue
|
||||
# 1576| getLValue(): [VariableAccess] d
|
||||
# 1576| Type = [LValueReferenceType] type &
|
||||
# 1576| ValueCategory = prvalue(load)
|
||||
# 1576| getRValue(): [Literal] 4.0
|
||||
# 1576| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1576| Value = [Literal] 4.0
|
||||
# 1576| ValueCategory = prvalue
|
||||
# 1576| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1576| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1576| ValueCategory = lvalue
|
||||
# 1577| getStmt(5): [DeclStmt] declaration
|
||||
# 1577| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rd
|
||||
# 1577| Type = [LValueReferenceType] double &
|
||||
# 1577| getVariable().getInitializer(): [Initializer] initializer for rd
|
||||
# 1577| getExpr(): [VariableAccess] d
|
||||
# 1577| Type = [LValueReferenceType] type &
|
||||
# 1577| ValueCategory = prvalue(load)
|
||||
# 1577| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1577| Type = [LValueReferenceType] type &
|
||||
# 1577| ValueCategory = prvalue
|
||||
# 1577| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1577| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1577| ValueCategory = lvalue
|
||||
# 1578| getStmt(6): [DeclStmt] declaration
|
||||
# 1578| getDeclarationEntry(0): [VariableDeclarationEntry] definition of v
|
||||
# 1578| Type = [IntType] int
|
||||
# 1578| getVariable().getInitializer(): [Initializer] initializer for v
|
||||
# 1578| getExpr(): [VariableAccess] i
|
||||
# 1578| Type = [LValueReferenceType] type &
|
||||
# 1578| ValueCategory = prvalue(load)
|
||||
# 1578| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1578| Type = [NestedTypedefType,UsingAliasTypedefType] type
|
||||
# 1578| ValueCategory = prvalue(load)
|
||||
# 1579| getStmt(7): [ExprStmt] ExprStmt
|
||||
# 1579| getExpr(): [AssignExpr] ... = ...
|
||||
# 1579| Type = [IntType] int
|
||||
# 1579| ValueCategory = lvalue
|
||||
# 1579| getLValue(): [VariableAccess] r
|
||||
# 1579| Type = [LValueReferenceType] int &
|
||||
# 1579| ValueCategory = prvalue(load)
|
||||
# 1579| getRValue(): [Literal] 5
|
||||
# 1579| Type = [IntType] int
|
||||
# 1579| Value = [Literal] 5
|
||||
# 1579| ValueCategory = prvalue
|
||||
# 1579| getLValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1579| Type = [IntType] int
|
||||
# 1579| ValueCategory = lvalue
|
||||
# 1580| getStmt(8): [DeclStmt] declaration
|
||||
# 1580| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rr
|
||||
# 1580| Type = [LValueReferenceType] int &
|
||||
# 1580| getVariable().getInitializer(): [Initializer] initializer for rr
|
||||
# 1580| getExpr(): [VariableAccess] r
|
||||
# 1580| Type = [LValueReferenceType] int &
|
||||
# 1580| ValueCategory = prvalue(load)
|
||||
# 1580| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 1580| Type = [LValueReferenceType] int &
|
||||
# 1580| ValueCategory = prvalue
|
||||
# 1580| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1580| Type = [IntType] int
|
||||
# 1580| ValueCategory = lvalue
|
||||
# 1581| getStmt(9): [DeclStmt] declaration
|
||||
# 1581| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
|
||||
# 1581| Type = [IntType] int
|
||||
# 1581| getVariable().getInitializer(): [Initializer] initializer for w
|
||||
# 1581| getExpr(): [VariableAccess] r
|
||||
# 1581| Type = [LValueReferenceType] int &
|
||||
# 1581| ValueCategory = prvalue(load)
|
||||
# 1581| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1581| Type = [IntType] int
|
||||
# 1581| ValueCategory = prvalue(load)
|
||||
# 1583| getStmt(3): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -1458,4 +1458,128 @@ struct Inheritance_Test_A : public Inheritance_Test_B {
|
||||
y = 3;
|
||||
}
|
||||
};
|
||||
|
||||
void array_structured_binding() {
|
||||
int xs[2] = {1, 2};
|
||||
// structured binding use
|
||||
{
|
||||
auto& [x0, x1] = xs;
|
||||
x1 = 3;
|
||||
int &rx1 = x1;
|
||||
int x = x1;
|
||||
}
|
||||
// explicit reference version
|
||||
{
|
||||
auto& unnamed_local_variable = xs;
|
||||
auto& x0 = xs[0];
|
||||
auto& x1 = xs[1];
|
||||
x1 = 3;
|
||||
int &rx1 = x1;
|
||||
int x = x1;
|
||||
}
|
||||
}
|
||||
|
||||
struct StructuredBindingDataMemberStruct {
|
||||
int i = 1;
|
||||
double d = 2.0;
|
||||
unsigned int b : 3;
|
||||
int& r = i;
|
||||
};
|
||||
|
||||
void data_member_structured_binding() {
|
||||
StructuredBindingDataMemberStruct s;
|
||||
// structured binding use
|
||||
{
|
||||
auto [i, d, b, r] = s;
|
||||
d = 4.0;
|
||||
double& rd = d;
|
||||
int v = i;
|
||||
r = 5;
|
||||
int& rr = r;
|
||||
int w = r;
|
||||
}
|
||||
// explicit reference version
|
||||
{
|
||||
auto unnamed_local_variable = s;
|
||||
auto& i = unnamed_local_variable.i;
|
||||
auto& d = unnamed_local_variable.d;
|
||||
// no equivalent for b
|
||||
auto& r = unnamed_local_variable.r;
|
||||
d = 4.0;
|
||||
double& rd = d;
|
||||
int v = i;
|
||||
r = 5;
|
||||
int& rr = r;
|
||||
int w = r;
|
||||
}
|
||||
}
|
||||
struct StructuredBindingTuple;
|
||||
|
||||
namespace std {
|
||||
template<typename T>
|
||||
struct tuple_size;
|
||||
template<>
|
||||
struct tuple_size<StructuredBindingTuple> {
|
||||
static const unsigned int value = 3;
|
||||
};
|
||||
|
||||
template<int, typename T>
|
||||
struct tuple_element;
|
||||
template<>
|
||||
struct tuple_element<0, StructuredBindingTuple> {
|
||||
using type = int;
|
||||
};
|
||||
template<>
|
||||
struct tuple_element<1, StructuredBindingTuple> {
|
||||
using type = double;
|
||||
};
|
||||
template<>
|
||||
struct tuple_element<2, StructuredBindingTuple> {
|
||||
using type = int&;
|
||||
};
|
||||
}
|
||||
|
||||
struct StructuredBindingTuple {
|
||||
int i = 1;
|
||||
double d = 2.2;
|
||||
int& r = i;
|
||||
|
||||
template<int i>
|
||||
typename std::tuple_element<i, StructuredBindingTuple>::type& get();
|
||||
};
|
||||
|
||||
template<>
|
||||
std::tuple_element<0, StructuredBindingTuple>::type& StructuredBindingTuple::get<0>() { return i; }
|
||||
template<>
|
||||
std::tuple_element<1, StructuredBindingTuple>::type& StructuredBindingTuple::get<1>() { return d; }
|
||||
template<>
|
||||
std::tuple_element<2, StructuredBindingTuple>::type& StructuredBindingTuple::get<2>() { return r; }
|
||||
|
||||
void tuple_structured_binding() {
|
||||
StructuredBindingTuple t;
|
||||
// structured binding use
|
||||
{
|
||||
auto [i, d, r] = t;
|
||||
d = 4.0;
|
||||
double& rd = d;
|
||||
int v = i;
|
||||
r = 5;
|
||||
int& rr = r;
|
||||
int w = r;
|
||||
}
|
||||
// explicit reference version
|
||||
{
|
||||
auto unnamed_local_variable = t;
|
||||
auto& i = unnamed_local_variable.get<0>();
|
||||
auto& d = unnamed_local_variable.get<1>();
|
||||
auto& r = unnamed_local_variable.get<2>();
|
||||
d = 4.0;
|
||||
double& rd = d;
|
||||
int v = i;
|
||||
r = 5;
|
||||
int& rr = r;
|
||||
int w = r;
|
||||
}
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -632,6 +632,7 @@
|
||||
| file://:0:0:0:0 | Address | &:r0_1 |
|
||||
| file://:0:0:0:0 | Address | &:r0_1 |
|
||||
| file://:0:0:0:0 | Address | &:r0_1 |
|
||||
| file://:0:0:0:0 | Address | &:r0_1 |
|
||||
| file://:0:0:0:0 | Address | &:r0_2 |
|
||||
| file://:0:0:0:0 | Address | &:r0_3 |
|
||||
| file://:0:0:0:0 | Address | &:r0_3 |
|
||||
@@ -653,6 +654,7 @@
|
||||
| file://:0:0:0:0 | Address | &:r0_8 |
|
||||
| file://:0:0:0:0 | Address | &:r0_8 |
|
||||
| file://:0:0:0:0 | Address | &:r0_8 |
|
||||
| file://:0:0:0:0 | Address | &:r0_8 |
|
||||
| file://:0:0:0:0 | Address | &:r0_9 |
|
||||
| file://:0:0:0:0 | Address | &:r0_9 |
|
||||
| file://:0:0:0:0 | Address | &:r0_10 |
|
||||
@@ -682,6 +684,8 @@
|
||||
| file://:0:0:0:0 | ChiTotal | total:m763_8 |
|
||||
| file://:0:0:0:0 | ChiTotal | total:m1043_10 |
|
||||
| file://:0:0:0:0 | ChiTotal | total:m1240_4 |
|
||||
| file://:0:0:0:0 | Left | r0_4 |
|
||||
| file://:0:0:0:0 | Left | r0_11 |
|
||||
| file://:0:0:0:0 | Load | m0_2 |
|
||||
| file://:0:0:0:0 | Load | m0_2 |
|
||||
| file://:0:0:0:0 | Load | m0_2 |
|
||||
@@ -689,7 +693,11 @@
|
||||
| file://:0:0:0:0 | Load | m745_6 |
|
||||
| file://:0:0:0:0 | Load | m754_6 |
|
||||
| file://:0:0:0:0 | Load | m763_6 |
|
||||
| file://:0:0:0:0 | Load | m1466_4 |
|
||||
| file://:0:0:0:0 | Load | m1466_4 |
|
||||
| file://:0:0:0:0 | Load | ~m1444_6 |
|
||||
| file://:0:0:0:0 | Right | r0_5 |
|
||||
| file://:0:0:0:0 | Right | r0_12 |
|
||||
| file://:0:0:0:0 | SideEffect | m0_4 |
|
||||
| file://:0:0:0:0 | SideEffect | m0_4 |
|
||||
| file://:0:0:0:0 | SideEffect | m0_4 |
|
||||
@@ -715,11 +723,17 @@
|
||||
| file://:0:0:0:0 | StoreValue | r0_1 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_1 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_1 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_1 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_1 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_3 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_6 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_13 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_13 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_22 |
|
||||
| file://:0:0:0:0 | StoreValue | r0_22 |
|
||||
| file://:0:0:0:0 | Unary | r0_1 |
|
||||
| file://:0:0:0:0 | Unary | r0_2 |
|
||||
| file://:0:0:0:0 | Unary | r0_3 |
|
||||
| file://:0:0:0:0 | Unary | r0_5 |
|
||||
| file://:0:0:0:0 | Unary | r0_5 |
|
||||
| file://:0:0:0:0 | Unary | r0_6 |
|
||||
@@ -730,6 +744,8 @@
|
||||
| file://:0:0:0:0 | Unary | r0_7 |
|
||||
| file://:0:0:0:0 | Unary | r0_8 |
|
||||
| file://:0:0:0:0 | Unary | r0_9 |
|
||||
| file://:0:0:0:0 | Unary | r0_9 |
|
||||
| file://:0:0:0:0 | Unary | r0_10 |
|
||||
| file://:0:0:0:0 | Unary | r0_10 |
|
||||
| file://:0:0:0:0 | Unary | r0_11 |
|
||||
| file://:0:0:0:0 | Unary | r0_12 |
|
||||
@@ -6656,6 +6672,426 @@
|
||||
| ir.cpp:1458:5:1458:9 | ChiPartial | partial:m1458_5 |
|
||||
| ir.cpp:1458:5:1458:9 | ChiTotal | total:m1457_12 |
|
||||
| ir.cpp:1458:9:1458:9 | StoreValue | r1458_1 |
|
||||
| ir.cpp:1462:6:1462:29 | ChiPartial | partial:m1462_3 |
|
||||
| ir.cpp:1462:6:1462:29 | ChiTotal | total:m1462_2 |
|
||||
| ir.cpp:1462:6:1462:29 | SideEffect | m1462_3 |
|
||||
| ir.cpp:1463:9:1463:10 | Address | &:r1463_1 |
|
||||
| ir.cpp:1463:9:1463:10 | Left | r1463_1 |
|
||||
| ir.cpp:1463:9:1463:10 | Left | r1463_1 |
|
||||
| ir.cpp:1463:16:1463:22 | Address | &:r1463_4 |
|
||||
| ir.cpp:1463:16:1463:22 | Address | &:r1463_9 |
|
||||
| ir.cpp:1463:16:1463:22 | Right | r1463_3 |
|
||||
| ir.cpp:1463:16:1463:22 | Right | r1463_8 |
|
||||
| ir.cpp:1463:18:1463:18 | ChiPartial | partial:m1463_6 |
|
||||
| ir.cpp:1463:18:1463:18 | ChiTotal | total:m1463_2 |
|
||||
| ir.cpp:1463:18:1463:18 | StoreValue | r1463_5 |
|
||||
| ir.cpp:1463:21:1463:21 | ChiPartial | partial:m1463_11 |
|
||||
| ir.cpp:1463:21:1463:21 | ChiTotal | total:m1463_7 |
|
||||
| ir.cpp:1463:21:1463:21 | StoreValue | r1463_10 |
|
||||
| ir.cpp:1466:15:1466:15 | Address | &:r1466_1 |
|
||||
| ir.cpp:1466:16:1466:16 | Address | &:r1466_5 |
|
||||
| ir.cpp:1466:20:1466:20 | Address | &:r1466_6 |
|
||||
| ir.cpp:1466:26:1466:27 | StoreValue | r1466_3 |
|
||||
| ir.cpp:1466:26:1466:27 | Unary | r1466_2 |
|
||||
| ir.cpp:1467:9:1467:10 | Address | &:r1467_2 |
|
||||
| ir.cpp:1467:14:1467:14 | StoreValue | r1467_1 |
|
||||
| ir.cpp:1468:14:1468:16 | Address | &:r1468_1 |
|
||||
| ir.cpp:1468:20:1468:21 | StoreValue | r1468_3 |
|
||||
| ir.cpp:1468:20:1468:21 | Unary | r1468_2 |
|
||||
| ir.cpp:1469:13:1469:13 | Address | &:r1469_1 |
|
||||
| ir.cpp:1469:17:1469:18 | Address | &:r1469_2 |
|
||||
| ir.cpp:1469:17:1469:18 | Load | m1467_3 |
|
||||
| ir.cpp:1469:17:1469:18 | StoreValue | r1469_3 |
|
||||
| ir.cpp:1473:15:1473:36 | Address | &:r1473_1 |
|
||||
| ir.cpp:1473:40:1473:41 | StoreValue | r1473_3 |
|
||||
| ir.cpp:1473:40:1473:41 | Unary | r1473_2 |
|
||||
| ir.cpp:1474:15:1474:16 | Address | &:r1474_1 |
|
||||
| ir.cpp:1474:20:1474:21 | Left | r1474_3 |
|
||||
| ir.cpp:1474:20:1474:21 | Unary | r1474_2 |
|
||||
| ir.cpp:1474:20:1474:24 | StoreValue | r1474_6 |
|
||||
| ir.cpp:1474:20:1474:24 | Unary | r1474_5 |
|
||||
| ir.cpp:1474:23:1474:23 | Right | r1474_4 |
|
||||
| ir.cpp:1475:15:1475:16 | Address | &:r1475_1 |
|
||||
| ir.cpp:1475:20:1475:21 | Left | r1475_3 |
|
||||
| ir.cpp:1475:20:1475:21 | Unary | r1475_2 |
|
||||
| ir.cpp:1475:20:1475:24 | StoreValue | r1475_6 |
|
||||
| ir.cpp:1475:20:1475:24 | Unary | r1475_5 |
|
||||
| ir.cpp:1475:23:1475:23 | Right | r1475_4 |
|
||||
| ir.cpp:1476:9:1476:10 | Address | &:r1476_2 |
|
||||
| ir.cpp:1476:9:1476:10 | Address | &:r1476_4 |
|
||||
| ir.cpp:1476:9:1476:10 | Load | m1475_7 |
|
||||
| ir.cpp:1476:9:1476:10 | Unary | r1476_3 |
|
||||
| ir.cpp:1476:9:1476:14 | ChiPartial | partial:m1476_5 |
|
||||
| ir.cpp:1476:9:1476:14 | ChiTotal | total:m1463_12 |
|
||||
| ir.cpp:1476:14:1476:14 | StoreValue | r1476_1 |
|
||||
| ir.cpp:1477:14:1477:16 | Address | &:r1477_1 |
|
||||
| ir.cpp:1477:20:1477:21 | Address | &:r1477_2 |
|
||||
| ir.cpp:1477:20:1477:21 | Load | m1475_7 |
|
||||
| ir.cpp:1477:20:1477:21 | StoreValue | r1477_5 |
|
||||
| ir.cpp:1477:20:1477:21 | Unary | r1477_3 |
|
||||
| ir.cpp:1477:20:1477:21 | Unary | r1477_4 |
|
||||
| ir.cpp:1478:13:1478:13 | Address | &:r1478_1 |
|
||||
| ir.cpp:1478:17:1478:18 | Address | &:r1478_2 |
|
||||
| ir.cpp:1478:17:1478:18 | Address | &:r1478_3 |
|
||||
| ir.cpp:1478:17:1478:18 | Load | m1475_7 |
|
||||
| ir.cpp:1478:17:1478:18 | Load | m1476_5 |
|
||||
| ir.cpp:1478:17:1478:18 | StoreValue | r1478_4 |
|
||||
| ir.cpp:1482:8:1482:8 | Address | &:r1482_5 |
|
||||
| ir.cpp:1482:8:1482:8 | Address | &:r1482_5 |
|
||||
| ir.cpp:1482:8:1482:8 | Address | &:r1482_7 |
|
||||
| ir.cpp:1482:8:1482:8 | Address | &:r1482_7 |
|
||||
| ir.cpp:1482:8:1482:8 | ChiPartial | partial:m1482_3 |
|
||||
| ir.cpp:1482:8:1482:8 | ChiTotal | total:m1482_2 |
|
||||
| ir.cpp:1482:8:1482:8 | Load | m1482_6 |
|
||||
| ir.cpp:1482:8:1482:8 | SideEffect | m1482_3 |
|
||||
| ir.cpp:1482:8:1482:8 | SideEffect | m1482_8 |
|
||||
| ir.cpp:1489:6:1489:35 | ChiPartial | partial:m1489_3 |
|
||||
| ir.cpp:1489:6:1489:35 | ChiTotal | total:m1489_2 |
|
||||
| ir.cpp:1489:6:1489:35 | SideEffect | ~m1511_6 |
|
||||
| ir.cpp:1490:39:1490:39 | Address | &:r1490_1 |
|
||||
| ir.cpp:1490:39:1490:39 | Address | &:r1490_1 |
|
||||
| ir.cpp:1490:39:1490:39 | Arg(this) | this:r1490_1 |
|
||||
| ir.cpp:1490:39:1490:39 | CallTarget | func:r1490_3 |
|
||||
| ir.cpp:1490:39:1490:39 | ChiPartial | partial:m1490_5 |
|
||||
| ir.cpp:1490:39:1490:39 | ChiPartial | partial:m1490_7 |
|
||||
| ir.cpp:1490:39:1490:39 | ChiTotal | total:m1489_4 |
|
||||
| ir.cpp:1490:39:1490:39 | ChiTotal | total:m1490_2 |
|
||||
| ir.cpp:1490:39:1490:39 | SideEffect | ~m1489_4 |
|
||||
| ir.cpp:1493:14:1493:14 | Address | &:r1493_1 |
|
||||
| ir.cpp:1493:15:1493:15 | Address | &:r1493_5 |
|
||||
| ir.cpp:1493:18:1493:18 | Address | &:r1493_9 |
|
||||
| ir.cpp:1493:21:1493:21 | Address | &:r1493_13 |
|
||||
| ir.cpp:1493:24:1493:24 | Address | &:r1493_17 |
|
||||
| ir.cpp:1493:29:1493:29 | Address | &:r1493_2 |
|
||||
| ir.cpp:1493:29:1493:29 | Load | m1490_8 |
|
||||
| ir.cpp:1493:29:1493:29 | StoreValue | r1493_3 |
|
||||
| ir.cpp:1493:30:1493:30 | Address | &:r1493_19 |
|
||||
| ir.cpp:1493:30:1493:30 | Load | ~m1493_4 |
|
||||
| ir.cpp:1493:30:1493:30 | StoreValue | r1493_7 |
|
||||
| ir.cpp:1493:30:1493:30 | StoreValue | r1493_11 |
|
||||
| ir.cpp:1493:30:1493:30 | StoreValue | r1493_15 |
|
||||
| ir.cpp:1493:30:1493:30 | StoreValue | r1493_21 |
|
||||
| ir.cpp:1493:30:1493:30 | Unary | r1493_6 |
|
||||
| ir.cpp:1493:30:1493:30 | Unary | r1493_10 |
|
||||
| ir.cpp:1493:30:1493:30 | Unary | r1493_14 |
|
||||
| ir.cpp:1493:30:1493:30 | Unary | r1493_18 |
|
||||
| ir.cpp:1493:30:1493:30 | Unary | r1493_20 |
|
||||
| ir.cpp:1494:9:1494:9 | Address | &:r1494_2 |
|
||||
| ir.cpp:1494:13:1494:15 | StoreValue | r1494_1 |
|
||||
| ir.cpp:1495:17:1495:18 | Address | &:r1495_1 |
|
||||
| ir.cpp:1495:22:1495:22 | StoreValue | r1495_3 |
|
||||
| ir.cpp:1495:22:1495:22 | Unary | r1495_2 |
|
||||
| ir.cpp:1496:13:1496:13 | Address | &:r1496_1 |
|
||||
| ir.cpp:1496:17:1496:17 | Address | &:r1496_2 |
|
||||
| ir.cpp:1496:17:1496:17 | Load | m1493_8 |
|
||||
| ir.cpp:1496:17:1496:17 | StoreValue | r1496_3 |
|
||||
| ir.cpp:1497:9:1497:9 | Address | &:r1497_2 |
|
||||
| ir.cpp:1497:13:1497:13 | StoreValue | r1497_1 |
|
||||
| ir.cpp:1498:14:1498:15 | Address | &:r1498_1 |
|
||||
| ir.cpp:1498:19:1498:19 | StoreValue | r1498_3 |
|
||||
| ir.cpp:1498:19:1498:19 | Unary | r1498_2 |
|
||||
| ir.cpp:1499:13:1499:13 | Address | &:r1499_1 |
|
||||
| ir.cpp:1499:17:1499:17 | Address | &:r1499_2 |
|
||||
| ir.cpp:1499:17:1499:17 | Load | m1497_3 |
|
||||
| ir.cpp:1499:17:1499:17 | StoreValue | r1499_3 |
|
||||
| ir.cpp:1503:14:1503:35 | Address | &:r1503_1 |
|
||||
| ir.cpp:1503:39:1503:39 | Address | &:r1503_2 |
|
||||
| ir.cpp:1503:39:1503:39 | Load | m1490_8 |
|
||||
| ir.cpp:1503:39:1503:39 | StoreValue | r1503_3 |
|
||||
| ir.cpp:1504:15:1504:15 | Address | &:r1504_1 |
|
||||
| ir.cpp:1504:19:1504:40 | Unary | r1504_2 |
|
||||
| ir.cpp:1504:19:1504:42 | StoreValue | r1504_4 |
|
||||
| ir.cpp:1504:42:1504:42 | Unary | r1504_3 |
|
||||
| ir.cpp:1505:15:1505:15 | Address | &:r1505_1 |
|
||||
| ir.cpp:1505:19:1505:40 | Unary | r1505_2 |
|
||||
| ir.cpp:1505:19:1505:42 | StoreValue | r1505_4 |
|
||||
| ir.cpp:1505:42:1505:42 | Unary | r1505_3 |
|
||||
| ir.cpp:1507:15:1507:15 | Address | &:r1507_1 |
|
||||
| ir.cpp:1507:19:1507:40 | Unary | r1507_2 |
|
||||
| ir.cpp:1507:19:1507:42 | StoreValue | r1507_6 |
|
||||
| ir.cpp:1507:19:1507:42 | Unary | r1507_5 |
|
||||
| ir.cpp:1507:42:1507:42 | Address | &:r1507_3 |
|
||||
| ir.cpp:1507:42:1507:42 | Load | ~m1503_4 |
|
||||
| ir.cpp:1507:42:1507:42 | Unary | r1507_4 |
|
||||
| ir.cpp:1508:9:1508:9 | Address | &:r1508_2 |
|
||||
| ir.cpp:1508:9:1508:9 | Address | &:r1508_4 |
|
||||
| ir.cpp:1508:9:1508:9 | Load | m1505_5 |
|
||||
| ir.cpp:1508:9:1508:9 | Unary | r1508_3 |
|
||||
| ir.cpp:1508:9:1508:15 | ChiPartial | partial:m1508_5 |
|
||||
| ir.cpp:1508:9:1508:15 | ChiTotal | total:m1503_4 |
|
||||
| ir.cpp:1508:13:1508:15 | StoreValue | r1508_1 |
|
||||
| ir.cpp:1509:17:1509:18 | Address | &:r1509_1 |
|
||||
| ir.cpp:1509:22:1509:22 | Address | &:r1509_2 |
|
||||
| ir.cpp:1509:22:1509:22 | Load | m1505_5 |
|
||||
| ir.cpp:1509:22:1509:22 | StoreValue | r1509_5 |
|
||||
| ir.cpp:1509:22:1509:22 | Unary | r1509_3 |
|
||||
| ir.cpp:1509:22:1509:22 | Unary | r1509_4 |
|
||||
| ir.cpp:1510:13:1510:13 | Address | &:r1510_1 |
|
||||
| ir.cpp:1510:17:1510:17 | Address | &:r1510_2 |
|
||||
| ir.cpp:1510:17:1510:17 | Address | &:r1510_3 |
|
||||
| ir.cpp:1510:17:1510:17 | Load | m1504_5 |
|
||||
| ir.cpp:1510:17:1510:17 | Load | ~m1503_4 |
|
||||
| ir.cpp:1510:17:1510:17 | StoreValue | r1510_4 |
|
||||
| ir.cpp:1511:9:1511:9 | Address | &:r1511_2 |
|
||||
| ir.cpp:1511:9:1511:9 | Address | &:r1511_4 |
|
||||
| ir.cpp:1511:9:1511:9 | Load | m1507_7 |
|
||||
| ir.cpp:1511:9:1511:9 | Unary | r1511_3 |
|
||||
| ir.cpp:1511:9:1511:13 | ChiPartial | partial:m1511_5 |
|
||||
| ir.cpp:1511:9:1511:13 | ChiTotal | total:m1490_6 |
|
||||
| ir.cpp:1511:13:1511:13 | StoreValue | r1511_1 |
|
||||
| ir.cpp:1512:14:1512:15 | Address | &:r1512_1 |
|
||||
| ir.cpp:1512:19:1512:19 | Address | &:r1512_2 |
|
||||
| ir.cpp:1512:19:1512:19 | Load | m1507_7 |
|
||||
| ir.cpp:1512:19:1512:19 | StoreValue | r1512_5 |
|
||||
| ir.cpp:1512:19:1512:19 | Unary | r1512_3 |
|
||||
| ir.cpp:1512:19:1512:19 | Unary | r1512_4 |
|
||||
| ir.cpp:1513:13:1513:13 | Address | &:r1513_1 |
|
||||
| ir.cpp:1513:17:1513:17 | Address | &:r1513_2 |
|
||||
| ir.cpp:1513:17:1513:17 | Address | &:r1513_3 |
|
||||
| ir.cpp:1513:17:1513:17 | Load | m1507_7 |
|
||||
| ir.cpp:1513:17:1513:17 | Load | ~m1511_6 |
|
||||
| ir.cpp:1513:17:1513:17 | StoreValue | r1513_4 |
|
||||
| ir.cpp:1542:8:1542:8 | Address | &:r1542_5 |
|
||||
| ir.cpp:1542:8:1542:8 | Address | &:r1542_5 |
|
||||
| ir.cpp:1542:8:1542:8 | Address | &:r1542_7 |
|
||||
| ir.cpp:1542:8:1542:8 | Address | &:r1542_7 |
|
||||
| ir.cpp:1542:8:1542:8 | ChiPartial | partial:m1542_3 |
|
||||
| ir.cpp:1542:8:1542:8 | ChiTotal | total:m1542_2 |
|
||||
| ir.cpp:1542:8:1542:8 | Load | m1542_6 |
|
||||
| ir.cpp:1542:8:1542:8 | SideEffect | m1542_3 |
|
||||
| ir.cpp:1542:8:1542:8 | SideEffect | m1542_8 |
|
||||
| ir.cpp:1552:54:1552:83 | Address | &:r1552_5 |
|
||||
| ir.cpp:1552:54:1552:83 | Address | &:r1552_5 |
|
||||
| ir.cpp:1552:54:1552:83 | Address | &:r1552_7 |
|
||||
| ir.cpp:1552:54:1552:83 | Address | &:r1552_7 |
|
||||
| ir.cpp:1552:54:1552:83 | Address | &:r1552_14 |
|
||||
| ir.cpp:1552:54:1552:83 | ChiPartial | partial:m1552_3 |
|
||||
| ir.cpp:1552:54:1552:83 | ChiTotal | total:m1552_2 |
|
||||
| ir.cpp:1552:54:1552:83 | Load | m0_2 |
|
||||
| ir.cpp:1552:54:1552:83 | Load | m1552_6 |
|
||||
| ir.cpp:1552:54:1552:83 | SideEffect | m1552_3 |
|
||||
| ir.cpp:1552:54:1552:83 | SideEffect | m1552_8 |
|
||||
| ir.cpp:1552:89:1552:97 | Address | &:r1552_9 |
|
||||
| ir.cpp:1552:96:1552:96 | Address | &:r1552_10 |
|
||||
| ir.cpp:1552:96:1552:96 | Load | m1552_6 |
|
||||
| ir.cpp:1552:96:1552:96 | Unary | r1552_11 |
|
||||
| ir.cpp:1552:96:1552:96 | Unary | r1552_12 |
|
||||
| ir.cpp:1554:54:1554:83 | Address | &:r1554_5 |
|
||||
| ir.cpp:1554:54:1554:83 | Address | &:r1554_5 |
|
||||
| ir.cpp:1554:54:1554:83 | Address | &:r1554_7 |
|
||||
| ir.cpp:1554:54:1554:83 | Address | &:r1554_7 |
|
||||
| ir.cpp:1554:54:1554:83 | Address | &:r1554_14 |
|
||||
| ir.cpp:1554:54:1554:83 | ChiPartial | partial:m1554_3 |
|
||||
| ir.cpp:1554:54:1554:83 | ChiTotal | total:m1554_2 |
|
||||
| ir.cpp:1554:54:1554:83 | Load | m0_2 |
|
||||
| ir.cpp:1554:54:1554:83 | Load | m1554_6 |
|
||||
| ir.cpp:1554:54:1554:83 | SideEffect | m1554_3 |
|
||||
| ir.cpp:1554:54:1554:83 | SideEffect | m1554_8 |
|
||||
| ir.cpp:1554:89:1554:97 | Address | &:r1554_9 |
|
||||
| ir.cpp:1554:96:1554:96 | Address | &:r1554_10 |
|
||||
| ir.cpp:1554:96:1554:96 | Load | m1554_6 |
|
||||
| ir.cpp:1554:96:1554:96 | Unary | r1554_11 |
|
||||
| ir.cpp:1554:96:1554:96 | Unary | r1554_12 |
|
||||
| ir.cpp:1556:54:1556:83 | Address | &:r1556_5 |
|
||||
| ir.cpp:1556:54:1556:83 | Address | &:r1556_5 |
|
||||
| ir.cpp:1556:54:1556:83 | Address | &:r1556_7 |
|
||||
| ir.cpp:1556:54:1556:83 | Address | &:r1556_7 |
|
||||
| ir.cpp:1556:54:1556:83 | Address | &:r1556_18 |
|
||||
| ir.cpp:1556:54:1556:83 | ChiPartial | partial:m1556_3 |
|
||||
| ir.cpp:1556:54:1556:83 | ChiTotal | total:m1556_2 |
|
||||
| ir.cpp:1556:54:1556:83 | Load | m1556_6 |
|
||||
| ir.cpp:1556:54:1556:83 | Load | m1556_16 |
|
||||
| ir.cpp:1556:54:1556:83 | SideEffect | m1556_3 |
|
||||
| ir.cpp:1556:54:1556:83 | SideEffect | m1556_8 |
|
||||
| ir.cpp:1556:89:1556:97 | Address | &:r1556_9 |
|
||||
| ir.cpp:1556:96:1556:96 | Address | &:r1556_10 |
|
||||
| ir.cpp:1556:96:1556:96 | Address | &:r1556_12 |
|
||||
| ir.cpp:1556:96:1556:96 | Load | m1556_6 |
|
||||
| ir.cpp:1556:96:1556:96 | Load | ~m1556_8 |
|
||||
| ir.cpp:1556:96:1556:96 | StoreValue | r1556_15 |
|
||||
| ir.cpp:1556:96:1556:96 | Unary | r1556_11 |
|
||||
| ir.cpp:1556:96:1556:96 | Unary | r1556_13 |
|
||||
| ir.cpp:1556:96:1556:96 | Unary | r1556_14 |
|
||||
| ir.cpp:1558:6:1558:29 | ChiPartial | partial:m1558_3 |
|
||||
| ir.cpp:1558:6:1558:29 | ChiTotal | total:m1558_2 |
|
||||
| ir.cpp:1558:6:1558:29 | SideEffect | ~m1579_6 |
|
||||
| ir.cpp:1559:28:1559:28 | Address | &:r1559_1 |
|
||||
| ir.cpp:1559:28:1559:28 | Address | &:r1559_1 |
|
||||
| ir.cpp:1559:28:1559:28 | Arg(this) | this:r1559_1 |
|
||||
| ir.cpp:1559:28:1559:28 | CallTarget | func:r1559_3 |
|
||||
| ir.cpp:1559:28:1559:28 | ChiPartial | partial:m1559_5 |
|
||||
| ir.cpp:1559:28:1559:28 | ChiPartial | partial:m1559_7 |
|
||||
| ir.cpp:1559:28:1559:28 | ChiTotal | total:m1558_4 |
|
||||
| ir.cpp:1559:28:1559:28 | ChiTotal | total:m1559_2 |
|
||||
| ir.cpp:1559:28:1559:28 | SideEffect | ~m1558_4 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_1 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_6 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_6 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_18 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_18 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_30 |
|
||||
| ir.cpp:1562:14:1562:14 | Address | &:r1562_30 |
|
||||
| ir.cpp:1562:14:1562:14 | Arg(this) | this:r1562_6 |
|
||||
| ir.cpp:1562:14:1562:14 | Arg(this) | this:r1562_18 |
|
||||
| ir.cpp:1562:14:1562:14 | Arg(this) | this:r1562_30 |
|
||||
| ir.cpp:1562:14:1562:14 | CallTarget | func:r1562_7 |
|
||||
| ir.cpp:1562:14:1562:14 | CallTarget | func:r1562_19 |
|
||||
| ir.cpp:1562:14:1562:14 | CallTarget | func:r1562_31 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiPartial | partial:m1562_9 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiPartial | partial:m1562_12 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiPartial | partial:m1562_21 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiPartial | partial:m1562_24 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiPartial | partial:m1562_33 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiPartial | partial:m1562_36 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiTotal | total:m1559_6 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiTotal | total:m1562_4 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiTotal | total:m1562_10 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiTotal | total:m1562_13 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiTotal | total:m1562_22 |
|
||||
| ir.cpp:1562:14:1562:14 | ChiTotal | total:m1562_25 |
|
||||
| ir.cpp:1562:14:1562:14 | SideEffect | m1562_4 |
|
||||
| ir.cpp:1562:14:1562:14 | SideEffect | m1562_13 |
|
||||
| ir.cpp:1562:14:1562:14 | SideEffect | m1562_25 |
|
||||
| ir.cpp:1562:14:1562:14 | SideEffect | ~m1559_6 |
|
||||
| ir.cpp:1562:14:1562:14 | SideEffect | ~m1562_10 |
|
||||
| ir.cpp:1562:14:1562:14 | SideEffect | ~m1562_22 |
|
||||
| ir.cpp:1562:14:1562:14 | Unary | r1562_8 |
|
||||
| ir.cpp:1562:14:1562:14 | Unary | r1562_20 |
|
||||
| ir.cpp:1562:14:1562:14 | Unary | r1562_32 |
|
||||
| ir.cpp:1562:14:1562:27 | StoreValue | r1562_15 |
|
||||
| ir.cpp:1562:14:1562:27 | StoreValue | r1562_27 |
|
||||
| ir.cpp:1562:14:1562:27 | StoreValue | r1562_39 |
|
||||
| ir.cpp:1562:14:1562:27 | Unary | r1562_14 |
|
||||
| ir.cpp:1562:14:1562:27 | Unary | r1562_26 |
|
||||
| ir.cpp:1562:14:1562:27 | Unary | r1562_38 |
|
||||
| ir.cpp:1562:15:1562:15 | Address | &:r1562_5 |
|
||||
| ir.cpp:1562:18:1562:18 | Address | &:r1562_17 |
|
||||
| ir.cpp:1562:21:1562:21 | Address | &:r1562_29 |
|
||||
| ir.cpp:1562:26:1562:26 | Address | &:r1562_2 |
|
||||
| ir.cpp:1562:26:1562:26 | Load | m1559_8 |
|
||||
| ir.cpp:1562:26:1562:26 | StoreValue | r1562_3 |
|
||||
| ir.cpp:1563:9:1563:9 | Address | &:r1563_2 |
|
||||
| ir.cpp:1563:9:1563:9 | Address | &:r1563_4 |
|
||||
| ir.cpp:1563:9:1563:9 | Load | m1562_28 |
|
||||
| ir.cpp:1563:9:1563:9 | Unary | r1563_3 |
|
||||
| ir.cpp:1563:9:1563:15 | ChiPartial | partial:m1563_5 |
|
||||
| ir.cpp:1563:9:1563:15 | ChiTotal | total:m1562_37 |
|
||||
| ir.cpp:1563:13:1563:15 | StoreValue | r1563_1 |
|
||||
| ir.cpp:1564:17:1564:18 | Address | &:r1564_1 |
|
||||
| ir.cpp:1564:22:1564:22 | Address | &:r1564_2 |
|
||||
| ir.cpp:1564:22:1564:22 | Load | m1562_28 |
|
||||
| ir.cpp:1564:22:1564:22 | StoreValue | r1564_5 |
|
||||
| ir.cpp:1564:22:1564:22 | Unary | r1564_3 |
|
||||
| ir.cpp:1564:22:1564:22 | Unary | r1564_4 |
|
||||
| ir.cpp:1565:13:1565:13 | Address | &:r1565_1 |
|
||||
| ir.cpp:1565:17:1565:17 | Address | &:r1565_2 |
|
||||
| ir.cpp:1565:17:1565:17 | Address | &:r1565_3 |
|
||||
| ir.cpp:1565:17:1565:17 | Load | m1562_16 |
|
||||
| ir.cpp:1565:17:1565:17 | Load | ~m1562_37 |
|
||||
| ir.cpp:1565:17:1565:17 | StoreValue | r1565_4 |
|
||||
| ir.cpp:1566:9:1566:9 | Address | &:r1566_2 |
|
||||
| ir.cpp:1566:9:1566:9 | Address | &:r1566_4 |
|
||||
| ir.cpp:1566:9:1566:9 | Load | m1562_40 |
|
||||
| ir.cpp:1566:9:1566:9 | Unary | r1566_3 |
|
||||
| ir.cpp:1566:9:1566:13 | ChiPartial | partial:m1566_5 |
|
||||
| ir.cpp:1566:9:1566:13 | ChiTotal | total:m1562_34 |
|
||||
| ir.cpp:1566:13:1566:13 | StoreValue | r1566_1 |
|
||||
| ir.cpp:1567:14:1567:15 | Address | &:r1567_1 |
|
||||
| ir.cpp:1567:19:1567:19 | Address | &:r1567_2 |
|
||||
| ir.cpp:1567:19:1567:19 | Load | m1562_40 |
|
||||
| ir.cpp:1567:19:1567:19 | StoreValue | r1567_5 |
|
||||
| ir.cpp:1567:19:1567:19 | Unary | r1567_3 |
|
||||
| ir.cpp:1567:19:1567:19 | Unary | r1567_4 |
|
||||
| ir.cpp:1568:13:1568:13 | Address | &:r1568_1 |
|
||||
| ir.cpp:1568:17:1568:17 | Address | &:r1568_2 |
|
||||
| ir.cpp:1568:17:1568:17 | Address | &:r1568_3 |
|
||||
| ir.cpp:1568:17:1568:17 | Load | m1562_40 |
|
||||
| ir.cpp:1568:17:1568:17 | Load | ~m1566_6 |
|
||||
| ir.cpp:1568:17:1568:17 | StoreValue | r1568_4 |
|
||||
| ir.cpp:1572:14:1572:35 | Address | &:r1572_1 |
|
||||
| ir.cpp:1572:39:1572:39 | Address | &:r1572_2 |
|
||||
| ir.cpp:1572:39:1572:39 | Load | m1559_8 |
|
||||
| ir.cpp:1572:39:1572:39 | StoreValue | r1572_3 |
|
||||
| ir.cpp:1573:15:1573:15 | Address | &:r1573_1 |
|
||||
| ir.cpp:1573:19:1573:40 | Address | &:r1573_2 |
|
||||
| ir.cpp:1573:19:1573:40 | Address | &:r1573_2 |
|
||||
| ir.cpp:1573:19:1573:40 | Arg(this) | this:r1573_2 |
|
||||
| ir.cpp:1573:19:1573:40 | ChiPartial | partial:m1573_8 |
|
||||
| ir.cpp:1573:19:1573:40 | ChiTotal | total:m1572_4 |
|
||||
| ir.cpp:1573:19:1573:40 | SideEffect | m1572_4 |
|
||||
| ir.cpp:1573:42:1573:47 | CallTarget | func:r1573_3 |
|
||||
| ir.cpp:1573:42:1573:47 | ChiPartial | partial:m1573_5 |
|
||||
| ir.cpp:1573:42:1573:47 | ChiTotal | total:m1566_6 |
|
||||
| ir.cpp:1573:42:1573:47 | SideEffect | ~m1566_6 |
|
||||
| ir.cpp:1573:42:1573:47 | Unary | r1573_4 |
|
||||
| ir.cpp:1573:42:1573:50 | StoreValue | r1573_11 |
|
||||
| ir.cpp:1573:42:1573:50 | Unary | r1573_10 |
|
||||
| ir.cpp:1574:15:1574:15 | Address | &:r1574_1 |
|
||||
| ir.cpp:1574:19:1574:40 | Address | &:r1574_2 |
|
||||
| ir.cpp:1574:19:1574:40 | Address | &:r1574_2 |
|
||||
| ir.cpp:1574:19:1574:40 | Arg(this) | this:r1574_2 |
|
||||
| ir.cpp:1574:19:1574:40 | ChiPartial | partial:m1574_8 |
|
||||
| ir.cpp:1574:19:1574:40 | ChiTotal | total:m1573_9 |
|
||||
| ir.cpp:1574:19:1574:40 | SideEffect | m1573_9 |
|
||||
| ir.cpp:1574:42:1574:47 | CallTarget | func:r1574_3 |
|
||||
| ir.cpp:1574:42:1574:47 | ChiPartial | partial:m1574_5 |
|
||||
| ir.cpp:1574:42:1574:47 | ChiTotal | total:m1573_6 |
|
||||
| ir.cpp:1574:42:1574:47 | SideEffect | ~m1573_6 |
|
||||
| ir.cpp:1574:42:1574:47 | Unary | r1574_4 |
|
||||
| ir.cpp:1574:42:1574:50 | StoreValue | r1574_11 |
|
||||
| ir.cpp:1574:42:1574:50 | Unary | r1574_10 |
|
||||
| ir.cpp:1575:15:1575:15 | Address | &:r1575_1 |
|
||||
| ir.cpp:1575:19:1575:40 | Address | &:r1575_2 |
|
||||
| ir.cpp:1575:19:1575:40 | Address | &:r1575_2 |
|
||||
| ir.cpp:1575:19:1575:40 | Arg(this) | this:r1575_2 |
|
||||
| ir.cpp:1575:19:1575:40 | ChiPartial | partial:m1575_8 |
|
||||
| ir.cpp:1575:19:1575:40 | ChiTotal | total:m1574_9 |
|
||||
| ir.cpp:1575:19:1575:40 | SideEffect | m1574_9 |
|
||||
| ir.cpp:1575:42:1575:47 | CallTarget | func:r1575_3 |
|
||||
| ir.cpp:1575:42:1575:47 | ChiPartial | partial:m1575_5 |
|
||||
| ir.cpp:1575:42:1575:47 | ChiTotal | total:m1574_6 |
|
||||
| ir.cpp:1575:42:1575:47 | SideEffect | ~m1574_6 |
|
||||
| ir.cpp:1575:42:1575:47 | Unary | r1575_4 |
|
||||
| ir.cpp:1575:42:1575:50 | StoreValue | r1575_11 |
|
||||
| ir.cpp:1575:42:1575:50 | Unary | r1575_10 |
|
||||
| ir.cpp:1576:9:1576:9 | Address | &:r1576_2 |
|
||||
| ir.cpp:1576:9:1576:9 | Address | &:r1576_4 |
|
||||
| ir.cpp:1576:9:1576:9 | Load | m1574_12 |
|
||||
| ir.cpp:1576:9:1576:9 | Unary | r1576_3 |
|
||||
| ir.cpp:1576:9:1576:15 | ChiPartial | partial:m1576_5 |
|
||||
| ir.cpp:1576:9:1576:15 | ChiTotal | total:m1575_9 |
|
||||
| ir.cpp:1576:13:1576:15 | StoreValue | r1576_1 |
|
||||
| ir.cpp:1577:17:1577:18 | Address | &:r1577_1 |
|
||||
| ir.cpp:1577:22:1577:22 | Address | &:r1577_2 |
|
||||
| ir.cpp:1577:22:1577:22 | Load | m1574_12 |
|
||||
| ir.cpp:1577:22:1577:22 | StoreValue | r1577_5 |
|
||||
| ir.cpp:1577:22:1577:22 | Unary | r1577_3 |
|
||||
| ir.cpp:1577:22:1577:22 | Unary | r1577_4 |
|
||||
| ir.cpp:1578:13:1578:13 | Address | &:r1578_1 |
|
||||
| ir.cpp:1578:17:1578:17 | Address | &:r1578_2 |
|
||||
| ir.cpp:1578:17:1578:17 | Address | &:r1578_3 |
|
||||
| ir.cpp:1578:17:1578:17 | Load | m1573_12 |
|
||||
| ir.cpp:1578:17:1578:17 | Load | ~m1575_9 |
|
||||
| ir.cpp:1578:17:1578:17 | StoreValue | r1578_4 |
|
||||
| ir.cpp:1579:9:1579:9 | Address | &:r1579_2 |
|
||||
| ir.cpp:1579:9:1579:9 | Address | &:r1579_4 |
|
||||
| ir.cpp:1579:9:1579:9 | Load | m1575_12 |
|
||||
| ir.cpp:1579:9:1579:9 | Unary | r1579_3 |
|
||||
| ir.cpp:1579:9:1579:13 | ChiPartial | partial:m1579_5 |
|
||||
| ir.cpp:1579:9:1579:13 | ChiTotal | total:m1575_6 |
|
||||
| ir.cpp:1579:13:1579:13 | StoreValue | r1579_1 |
|
||||
| ir.cpp:1580:14:1580:15 | Address | &:r1580_1 |
|
||||
| ir.cpp:1580:19:1580:19 | Address | &:r1580_2 |
|
||||
| ir.cpp:1580:19:1580:19 | Load | m1575_12 |
|
||||
| ir.cpp:1580:19:1580:19 | StoreValue | r1580_5 |
|
||||
| ir.cpp:1580:19:1580:19 | Unary | r1580_3 |
|
||||
| ir.cpp:1580:19:1580:19 | Unary | r1580_4 |
|
||||
| ir.cpp:1581:13:1581:13 | Address | &:r1581_1 |
|
||||
| ir.cpp:1581:17:1581:17 | Address | &:r1581_2 |
|
||||
| ir.cpp:1581:17:1581:17 | Address | &:r1581_3 |
|
||||
| ir.cpp:1581:17:1581:17 | Load | m1575_12 |
|
||||
| ir.cpp:1581:17:1581:17 | Load | ~m1579_6 |
|
||||
| ir.cpp:1581:17:1581:17 | StoreValue | r1581_4 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
|
||||
|
||||
@@ -7896,6 +7896,447 @@ ir.cpp:
|
||||
# 1457| v1457_13(void) = AliasedUse : ~m?
|
||||
# 1457| v1457_14(void) = ExitFunction :
|
||||
|
||||
# 1462| void array_structured_binding()
|
||||
# 1462| Block 0
|
||||
# 1462| v1462_1(void) = EnterFunction :
|
||||
# 1462| mu1462_2(unknown) = AliasedDefinition :
|
||||
# 1462| mu1462_3(unknown) = InitializeNonLocal :
|
||||
# 1463| r1463_1(glval<int[2]>) = VariableAddress[xs] :
|
||||
# 1463| mu1463_2(int[2]) = Uninitialized[xs] : &:r1463_1
|
||||
# 1463| r1463_3(int) = Constant[0] :
|
||||
# 1463| r1463_4(glval<int>) = PointerAdd[4] : r1463_1, r1463_3
|
||||
# 1463| r1463_5(int) = Constant[1] :
|
||||
# 1463| mu1463_6(int) = Store[?] : &:r1463_4, r1463_5
|
||||
# 1463| r1463_7(int) = Constant[1] :
|
||||
# 1463| r1463_8(glval<int>) = PointerAdd[4] : r1463_1, r1463_7
|
||||
# 1463| r1463_9(int) = Constant[2] :
|
||||
# 1463| mu1463_10(int) = Store[?] : &:r1463_8, r1463_9
|
||||
# 1466| r1466_1(glval<int(&)[2]>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1466| r1466_2(glval<int[2]>) = VariableAddress[xs] :
|
||||
# 1466| r1466_3(int(&)[2]) = CopyValue : r1466_2
|
||||
# 1466| mu1466_4(int(&)[2]) = Store[(unnamed local variable)] : &:r1466_1, r1466_3
|
||||
# 1466| r1466_5(glval<int>) = VariableAddress[x0] :
|
||||
#-----| r0_1(glval<int(&)[2]>) = VariableAddress[(unnamed local variable)] :
|
||||
#-----| r0_2(int(&)[2]) = Load[(unnamed local variable)] : &:r0_1, ~m?
|
||||
#-----| r0_3(glval<int[2]>) = CopyValue : r0_2
|
||||
#-----| r0_4(int *) = Convert : r0_3
|
||||
#-----| r0_5(unsigned long) = Constant[0] :
|
||||
#-----| r0_6(glval<int>) = PointerAdd[4] : r0_4, r0_5
|
||||
#-----| mu0_7(int) = Store[x0] : &:r1466_5, r0_6
|
||||
# 1466| r1466_6(glval<int>) = VariableAddress[x1] :
|
||||
#-----| r0_8(glval<int(&)[2]>) = VariableAddress[(unnamed local variable)] :
|
||||
#-----| r0_9(int(&)[2]) = Load[(unnamed local variable)] : &:r0_8, ~m?
|
||||
#-----| r0_10(glval<int[2]>) = CopyValue : r0_9
|
||||
#-----| r0_11(int *) = Convert : r0_10
|
||||
#-----| r0_12(unsigned long) = Constant[1] :
|
||||
#-----| r0_13(glval<int>) = PointerAdd[4] : r0_11, r0_12
|
||||
#-----| mu0_14(int) = Store[x1] : &:r1466_6, r0_13
|
||||
# 1467| r1467_1(int) = Constant[3] :
|
||||
# 1467| r1467_2(glval<int>) = VariableAddress[x1] :
|
||||
# 1467| mu1467_3(int) = Store[x1] : &:r1467_2, r1467_1
|
||||
# 1468| r1468_1(glval<int &>) = VariableAddress[rx1] :
|
||||
# 1468| r1468_2(glval<int>) = VariableAddress[x1] :
|
||||
# 1468| r1468_3(int &) = CopyValue : r1468_2
|
||||
# 1468| mu1468_4(int &) = Store[rx1] : &:r1468_1, r1468_3
|
||||
# 1469| r1469_1(glval<int>) = VariableAddress[x] :
|
||||
# 1469| r1469_2(glval<int>) = VariableAddress[x1] :
|
||||
# 1469| r1469_3(int) = Load[x1] : &:r1469_2, ~m?
|
||||
# 1469| mu1469_4(int) = Store[x] : &:r1469_1, r1469_3
|
||||
# 1473| r1473_1(glval<int(&)[2]>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1473| r1473_2(glval<int[2]>) = VariableAddress[xs] :
|
||||
# 1473| r1473_3(int(&)[2]) = CopyValue : r1473_2
|
||||
# 1473| mu1473_4(int(&)[2]) = Store[unnamed_local_variable] : &:r1473_1, r1473_3
|
||||
# 1474| r1474_1(glval<int &>) = VariableAddress[x0] :
|
||||
# 1474| r1474_2(glval<int[2]>) = VariableAddress[xs] :
|
||||
# 1474| r1474_3(int *) = Convert : r1474_2
|
||||
# 1474| r1474_4(int) = Constant[0] :
|
||||
# 1474| r1474_5(glval<int>) = PointerAdd[4] : r1474_3, r1474_4
|
||||
# 1474| r1474_6(int &) = CopyValue : r1474_5
|
||||
# 1474| mu1474_7(int &) = Store[x0] : &:r1474_1, r1474_6
|
||||
# 1475| r1475_1(glval<int &>) = VariableAddress[x1] :
|
||||
# 1475| r1475_2(glval<int[2]>) = VariableAddress[xs] :
|
||||
# 1475| r1475_3(int *) = Convert : r1475_2
|
||||
# 1475| r1475_4(int) = Constant[1] :
|
||||
# 1475| r1475_5(glval<int>) = PointerAdd[4] : r1475_3, r1475_4
|
||||
# 1475| r1475_6(int &) = CopyValue : r1475_5
|
||||
# 1475| mu1475_7(int &) = Store[x1] : &:r1475_1, r1475_6
|
||||
# 1476| r1476_1(int) = Constant[3] :
|
||||
# 1476| r1476_2(glval<int &>) = VariableAddress[x1] :
|
||||
# 1476| r1476_3(int &) = Load[x1] : &:r1476_2, ~m?
|
||||
# 1476| r1476_4(glval<int>) = CopyValue : r1476_3
|
||||
# 1476| mu1476_5(int) = Store[?] : &:r1476_4, r1476_1
|
||||
# 1477| r1477_1(glval<int &>) = VariableAddress[rx1] :
|
||||
# 1477| r1477_2(glval<int &>) = VariableAddress[x1] :
|
||||
# 1477| r1477_3(int &) = Load[x1] : &:r1477_2, ~m?
|
||||
# 1477| r1477_4(glval<int>) = CopyValue : r1477_3
|
||||
# 1477| r1477_5(int &) = CopyValue : r1477_4
|
||||
# 1477| mu1477_6(int &) = Store[rx1] : &:r1477_1, r1477_5
|
||||
# 1478| r1478_1(glval<int>) = VariableAddress[x] :
|
||||
# 1478| r1478_2(glval<int &>) = VariableAddress[x1] :
|
||||
# 1478| r1478_3(int &) = Load[x1] : &:r1478_2, ~m?
|
||||
# 1478| r1478_4(int) = Load[?] : &:r1478_3, ~m?
|
||||
# 1478| mu1478_5(int) = Store[x] : &:r1478_1, r1478_4
|
||||
# 1480| v1480_1(void) = NoOp :
|
||||
# 1462| v1462_4(void) = ReturnVoid :
|
||||
# 1462| v1462_5(void) = AliasedUse : ~m?
|
||||
# 1462| v1462_6(void) = ExitFunction :
|
||||
|
||||
# 1482| void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct()
|
||||
# 1482| Block 0
|
||||
# 1482| v1482_1(void) = EnterFunction :
|
||||
# 1482| mu1482_2(unknown) = AliasedDefinition :
|
||||
# 1482| mu1482_3(unknown) = InitializeNonLocal :
|
||||
# 1482| r1482_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1482| mu1482_5(glval<StructuredBindingDataMemberStruct>) = InitializeParameter[#this] : &:r1482_4
|
||||
# 1482| r1482_6(glval<StructuredBindingDataMemberStruct>) = Load[#this] : &:r1482_4, ~m?
|
||||
# 1482| mu1482_7(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1482_6
|
||||
# 1482| v1482_8(void) = NoOp :
|
||||
# 1482| v1482_9(void) = ReturnIndirection[#this] : &:r1482_6, ~m?
|
||||
# 1482| v1482_10(void) = ReturnVoid :
|
||||
# 1482| v1482_11(void) = AliasedUse : ~m?
|
||||
# 1482| v1482_12(void) = ExitFunction :
|
||||
|
||||
# 1489| void data_member_structured_binding()
|
||||
# 1489| Block 0
|
||||
# 1489| v1489_1(void) = EnterFunction :
|
||||
# 1489| mu1489_2(unknown) = AliasedDefinition :
|
||||
# 1489| mu1489_3(unknown) = InitializeNonLocal :
|
||||
# 1490| r1490_1(glval<StructuredBindingDataMemberStruct>) = VariableAddress[s] :
|
||||
# 1490| mu1490_2(StructuredBindingDataMemberStruct) = Uninitialized[s] : &:r1490_1
|
||||
# 1490| r1490_3(glval<unknown>) = FunctionAddress[StructuredBindingDataMemberStruct] :
|
||||
# 1490| v1490_4(void) = Call[StructuredBindingDataMemberStruct] : func:r1490_3, this:r1490_1
|
||||
# 1490| mu1490_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 1490| mu1490_6(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1490_1
|
||||
# 1493| r1493_1(glval<StructuredBindingDataMemberStruct>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1493| r1493_2(glval<StructuredBindingDataMemberStruct>) = VariableAddress[s] :
|
||||
# 1493| r1493_3(StructuredBindingDataMemberStruct) = Load[s] : &:r1493_2, ~m?
|
||||
# 1493| mu1493_4(StructuredBindingDataMemberStruct) = Store[(unnamed local variable)] : &:r1493_1, r1493_3
|
||||
# 1493| r1493_5(glval<int>) = VariableAddress[i] :
|
||||
# 1493| r1493_6(glval<StructuredBindingDataMemberStruct>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1493| r1493_7(glval<int>) = FieldAddress[i] : r1493_6
|
||||
# 1493| mu1493_8(int) = Store[i] : &:r1493_5, r1493_7
|
||||
# 1493| r1493_9(glval<double>) = VariableAddress[d] :
|
||||
# 1493| r1493_10(glval<StructuredBindingDataMemberStruct>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1493| r1493_11(glval<double>) = FieldAddress[d] : r1493_10
|
||||
# 1493| mu1493_12(double) = Store[d] : &:r1493_9, r1493_11
|
||||
# 1493| r1493_13(glval<unsigned int>) = VariableAddress[b] :
|
||||
# 1493| r1493_14(glval<StructuredBindingDataMemberStruct>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1493| r1493_15(glval<unsigned int>) = FieldAddress[b] : r1493_14
|
||||
# 1493| mu1493_16(unsigned int) = Store[b] : &:r1493_13, r1493_15
|
||||
# 1493| r1493_17(glval<int>) = VariableAddress[r] :
|
||||
# 1493| r1493_18(glval<StructuredBindingDataMemberStruct>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1493| r1493_19(glval<int &>) = FieldAddress[r] : r1493_18
|
||||
# 1493| r1493_20(int &) = Load[?] : &:r1493_19, ~m?
|
||||
# 1493| r1493_21(glval<int>) = CopyValue : r1493_20
|
||||
# 1493| mu1493_22(int) = Store[r] : &:r1493_17, r1493_21
|
||||
# 1494| r1494_1(double) = Constant[4.0] :
|
||||
# 1494| r1494_2(glval<double>) = VariableAddress[d] :
|
||||
# 1494| mu1494_3(double) = Store[d] : &:r1494_2, r1494_1
|
||||
# 1495| r1495_1(glval<double &>) = VariableAddress[rd] :
|
||||
# 1495| r1495_2(glval<double>) = VariableAddress[d] :
|
||||
# 1495| r1495_3(double &) = CopyValue : r1495_2
|
||||
# 1495| mu1495_4(double &) = Store[rd] : &:r1495_1, r1495_3
|
||||
# 1496| r1496_1(glval<int>) = VariableAddress[v] :
|
||||
# 1496| r1496_2(glval<int>) = VariableAddress[i] :
|
||||
# 1496| r1496_3(int) = Load[i] : &:r1496_2, ~m?
|
||||
# 1496| mu1496_4(int) = Store[v] : &:r1496_1, r1496_3
|
||||
# 1497| r1497_1(int) = Constant[5] :
|
||||
# 1497| r1497_2(glval<int>) = VariableAddress[r] :
|
||||
# 1497| mu1497_3(int) = Store[r] : &:r1497_2, r1497_1
|
||||
# 1498| r1498_1(glval<int &>) = VariableAddress[rr] :
|
||||
# 1498| r1498_2(glval<int>) = VariableAddress[r] :
|
||||
# 1498| r1498_3(int &) = CopyValue : r1498_2
|
||||
# 1498| mu1498_4(int &) = Store[rr] : &:r1498_1, r1498_3
|
||||
# 1499| r1499_1(glval<int>) = VariableAddress[w] :
|
||||
# 1499| r1499_2(glval<int>) = VariableAddress[r] :
|
||||
# 1499| r1499_3(int) = Load[r] : &:r1499_2, ~m?
|
||||
# 1499| mu1499_4(int) = Store[w] : &:r1499_1, r1499_3
|
||||
# 1503| r1503_1(glval<StructuredBindingDataMemberStruct>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1503| r1503_2(glval<StructuredBindingDataMemberStruct>) = VariableAddress[s] :
|
||||
# 1503| r1503_3(StructuredBindingDataMemberStruct) = Load[s] : &:r1503_2, ~m?
|
||||
# 1503| mu1503_4(StructuredBindingDataMemberStruct) = Store[unnamed_local_variable] : &:r1503_1, r1503_3
|
||||
# 1504| r1504_1(glval<int &>) = VariableAddress[i] :
|
||||
# 1504| r1504_2(glval<StructuredBindingDataMemberStruct>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1504| r1504_3(glval<int>) = FieldAddress[i] : r1504_2
|
||||
# 1504| r1504_4(int &) = CopyValue : r1504_3
|
||||
# 1504| mu1504_5(int &) = Store[i] : &:r1504_1, r1504_4
|
||||
# 1505| r1505_1(glval<double &>) = VariableAddress[d] :
|
||||
# 1505| r1505_2(glval<StructuredBindingDataMemberStruct>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1505| r1505_3(glval<double>) = FieldAddress[d] : r1505_2
|
||||
# 1505| r1505_4(double &) = CopyValue : r1505_3
|
||||
# 1505| mu1505_5(double &) = Store[d] : &:r1505_1, r1505_4
|
||||
# 1507| r1507_1(glval<int &>) = VariableAddress[r] :
|
||||
# 1507| r1507_2(glval<StructuredBindingDataMemberStruct>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1507| r1507_3(glval<int &>) = FieldAddress[r] : r1507_2
|
||||
# 1507| r1507_4(int &) = Load[?] : &:r1507_3, ~m?
|
||||
# 1507| r1507_5(glval<int>) = CopyValue : r1507_4
|
||||
# 1507| r1507_6(int &) = CopyValue : r1507_5
|
||||
# 1507| mu1507_7(int &) = Store[r] : &:r1507_1, r1507_6
|
||||
# 1508| r1508_1(double) = Constant[4.0] :
|
||||
# 1508| r1508_2(glval<double &>) = VariableAddress[d] :
|
||||
# 1508| r1508_3(double &) = Load[d] : &:r1508_2, ~m?
|
||||
# 1508| r1508_4(glval<double>) = CopyValue : r1508_3
|
||||
# 1508| mu1508_5(double) = Store[?] : &:r1508_4, r1508_1
|
||||
# 1509| r1509_1(glval<double &>) = VariableAddress[rd] :
|
||||
# 1509| r1509_2(glval<double &>) = VariableAddress[d] :
|
||||
# 1509| r1509_3(double &) = Load[d] : &:r1509_2, ~m?
|
||||
# 1509| r1509_4(glval<double>) = CopyValue : r1509_3
|
||||
# 1509| r1509_5(double &) = CopyValue : r1509_4
|
||||
# 1509| mu1509_6(double &) = Store[rd] : &:r1509_1, r1509_5
|
||||
# 1510| r1510_1(glval<int>) = VariableAddress[v] :
|
||||
# 1510| r1510_2(glval<int &>) = VariableAddress[i] :
|
||||
# 1510| r1510_3(int &) = Load[i] : &:r1510_2, ~m?
|
||||
# 1510| r1510_4(int) = Load[?] : &:r1510_3, ~m?
|
||||
# 1510| mu1510_5(int) = Store[v] : &:r1510_1, r1510_4
|
||||
# 1511| r1511_1(int) = Constant[5] :
|
||||
# 1511| r1511_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1511| r1511_3(int &) = Load[r] : &:r1511_2, ~m?
|
||||
# 1511| r1511_4(glval<int>) = CopyValue : r1511_3
|
||||
# 1511| mu1511_5(int) = Store[?] : &:r1511_4, r1511_1
|
||||
# 1512| r1512_1(glval<int &>) = VariableAddress[rr] :
|
||||
# 1512| r1512_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1512| r1512_3(int &) = Load[r] : &:r1512_2, ~m?
|
||||
# 1512| r1512_4(glval<int>) = CopyValue : r1512_3
|
||||
# 1512| r1512_5(int &) = CopyValue : r1512_4
|
||||
# 1512| mu1512_6(int &) = Store[rr] : &:r1512_1, r1512_5
|
||||
# 1513| r1513_1(glval<int>) = VariableAddress[w] :
|
||||
# 1513| r1513_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1513| r1513_3(int &) = Load[r] : &:r1513_2, ~m?
|
||||
# 1513| r1513_4(int) = Load[?] : &:r1513_3, ~m?
|
||||
# 1513| mu1513_5(int) = Store[w] : &:r1513_1, r1513_4
|
||||
# 1515| v1515_1(void) = NoOp :
|
||||
# 1489| v1489_4(void) = ReturnVoid :
|
||||
# 1489| v1489_5(void) = AliasedUse : ~m?
|
||||
# 1489| v1489_6(void) = ExitFunction :
|
||||
|
||||
# 1542| void StructuredBindingTuple::StructuredBindingTuple()
|
||||
# 1542| Block 0
|
||||
# 1542| v1542_1(void) = EnterFunction :
|
||||
# 1542| mu1542_2(unknown) = AliasedDefinition :
|
||||
# 1542| mu1542_3(unknown) = InitializeNonLocal :
|
||||
# 1542| r1542_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1542| mu1542_5(glval<StructuredBindingTuple>) = InitializeParameter[#this] : &:r1542_4
|
||||
# 1542| r1542_6(glval<StructuredBindingTuple>) = Load[#this] : &:r1542_4, ~m?
|
||||
# 1542| mu1542_7(StructuredBindingTuple) = InitializeIndirection[#this] : &:r1542_6
|
||||
# 1542| v1542_8(void) = NoOp :
|
||||
# 1542| v1542_9(void) = ReturnIndirection[#this] : &:r1542_6, ~m?
|
||||
# 1542| v1542_10(void) = ReturnVoid :
|
||||
# 1542| v1542_11(void) = AliasedUse : ~m?
|
||||
# 1542| v1542_12(void) = ExitFunction :
|
||||
|
||||
# 1552| std::tuple_element<int 0, StructuredBindingTuple>::type& StructuredBindingTuple::get<int 0>()
|
||||
# 1552| Block 0
|
||||
# 1552| v1552_1(void) = EnterFunction :
|
||||
# 1552| mu1552_2(unknown) = AliasedDefinition :
|
||||
# 1552| mu1552_3(unknown) = InitializeNonLocal :
|
||||
# 1552| r1552_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1552| mu1552_5(glval<StructuredBindingTuple>) = InitializeParameter[#this] : &:r1552_4
|
||||
# 1552| r1552_6(glval<StructuredBindingTuple>) = Load[#this] : &:r1552_4, ~m?
|
||||
# 1552| mu1552_7(StructuredBindingTuple) = InitializeIndirection[#this] : &:r1552_6
|
||||
# 1552| r1552_8(glval<int &>) = VariableAddress[#return] :
|
||||
# 1552| r1552_9(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1552| r1552_10(StructuredBindingTuple *) = Load[#this] : &:r1552_9, ~m?
|
||||
# 1552| r1552_11(glval<int>) = FieldAddress[i] : r1552_10
|
||||
#-----| r0_1(int &) = CopyValue : r1552_11
|
||||
#-----| mu0_2(int &) = Store[#return] : &:r1552_8, r0_1
|
||||
# 1552| v1552_12(void) = ReturnIndirection[#this] : &:r1552_6, ~m?
|
||||
# 1552| r1552_13(glval<int &>) = VariableAddress[#return] :
|
||||
# 1552| v1552_14(void) = ReturnValue : &:r1552_13, ~m?
|
||||
# 1552| v1552_15(void) = AliasedUse : ~m?
|
||||
# 1552| v1552_16(void) = ExitFunction :
|
||||
|
||||
# 1554| std::tuple_element<int 1, StructuredBindingTuple>::type& StructuredBindingTuple::get<int 1>()
|
||||
# 1554| Block 0
|
||||
# 1554| v1554_1(void) = EnterFunction :
|
||||
# 1554| mu1554_2(unknown) = AliasedDefinition :
|
||||
# 1554| mu1554_3(unknown) = InitializeNonLocal :
|
||||
# 1554| r1554_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1554| mu1554_5(glval<StructuredBindingTuple>) = InitializeParameter[#this] : &:r1554_4
|
||||
# 1554| r1554_6(glval<StructuredBindingTuple>) = Load[#this] : &:r1554_4, ~m?
|
||||
# 1554| mu1554_7(StructuredBindingTuple) = InitializeIndirection[#this] : &:r1554_6
|
||||
# 1554| r1554_8(glval<double &>) = VariableAddress[#return] :
|
||||
# 1554| r1554_9(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1554| r1554_10(StructuredBindingTuple *) = Load[#this] : &:r1554_9, ~m?
|
||||
# 1554| r1554_11(glval<double>) = FieldAddress[d] : r1554_10
|
||||
#-----| r0_1(double &) = CopyValue : r1554_11
|
||||
#-----| mu0_2(double &) = Store[#return] : &:r1554_8, r0_1
|
||||
# 1554| v1554_12(void) = ReturnIndirection[#this] : &:r1554_6, ~m?
|
||||
# 1554| r1554_13(glval<double &>) = VariableAddress[#return] :
|
||||
# 1554| v1554_14(void) = ReturnValue : &:r1554_13, ~m?
|
||||
# 1554| v1554_15(void) = AliasedUse : ~m?
|
||||
# 1554| v1554_16(void) = ExitFunction :
|
||||
|
||||
# 1556| std::tuple_element<int 2, StructuredBindingTuple>::type StructuredBindingTuple::get<int 2>()
|
||||
# 1556| Block 0
|
||||
# 1556| v1556_1(void) = EnterFunction :
|
||||
# 1556| mu1556_2(unknown) = AliasedDefinition :
|
||||
# 1556| mu1556_3(unknown) = InitializeNonLocal :
|
||||
# 1556| r1556_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1556| mu1556_5(glval<StructuredBindingTuple>) = InitializeParameter[#this] : &:r1556_4
|
||||
# 1556| r1556_6(glval<StructuredBindingTuple>) = Load[#this] : &:r1556_4, ~m?
|
||||
# 1556| mu1556_7(StructuredBindingTuple) = InitializeIndirection[#this] : &:r1556_6
|
||||
# 1556| r1556_8(glval<int &>) = VariableAddress[#return] :
|
||||
# 1556| r1556_9(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1556| r1556_10(StructuredBindingTuple *) = Load[#this] : &:r1556_9, ~m?
|
||||
# 1556| r1556_11(glval<int &>) = FieldAddress[r] : r1556_10
|
||||
# 1556| r1556_12(int &) = Load[?] : &:r1556_11, ~m?
|
||||
# 1556| r1556_13(glval<int>) = CopyValue : r1556_12
|
||||
# 1556| r1556_14(int &) = CopyValue : r1556_13
|
||||
# 1556| mu1556_15(int &) = Store[#return] : &:r1556_8, r1556_14
|
||||
# 1556| v1556_16(void) = ReturnIndirection[#this] : &:r1556_6, ~m?
|
||||
# 1556| r1556_17(glval<int &>) = VariableAddress[#return] :
|
||||
# 1556| v1556_18(void) = ReturnValue : &:r1556_17, ~m?
|
||||
# 1556| v1556_19(void) = AliasedUse : ~m?
|
||||
# 1556| v1556_20(void) = ExitFunction :
|
||||
|
||||
# 1558| void tuple_structured_binding()
|
||||
# 1558| Block 0
|
||||
# 1558| v1558_1(void) = EnterFunction :
|
||||
# 1558| mu1558_2(unknown) = AliasedDefinition :
|
||||
# 1558| mu1558_3(unknown) = InitializeNonLocal :
|
||||
# 1559| r1559_1(glval<StructuredBindingTuple>) = VariableAddress[t] :
|
||||
# 1559| mu1559_2(StructuredBindingTuple) = Uninitialized[t] : &:r1559_1
|
||||
# 1559| r1559_3(glval<unknown>) = FunctionAddress[StructuredBindingTuple] :
|
||||
# 1559| v1559_4(void) = Call[StructuredBindingTuple] : func:r1559_3, this:r1559_1
|
||||
# 1559| mu1559_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 1559| mu1559_6(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1559_1
|
||||
# 1562| r1562_1(glval<StructuredBindingTuple>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1562| r1562_2(glval<StructuredBindingTuple>) = VariableAddress[t] :
|
||||
# 1562| r1562_3(StructuredBindingTuple) = Load[t] : &:r1562_2, ~m?
|
||||
# 1562| mu1562_4(StructuredBindingTuple) = Store[(unnamed local variable)] : &:r1562_1, r1562_3
|
||||
# 1562| r1562_5(glval<int &>) = VariableAddress[i] :
|
||||
# 1562| r1562_6(glval<StructuredBindingTuple>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1562| r1562_7(glval<unknown>) = FunctionAddress[get] :
|
||||
# 1562| r1562_8(int &) = Call[get] : func:r1562_7, this:r1562_6
|
||||
# 1562| mu1562_9(unknown) = ^CallSideEffect : ~m?
|
||||
# 1562| v1562_10(void) = ^IndirectReadSideEffect[-1] : &:r1562_6, ~m?
|
||||
# 1562| mu1562_11(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1562_6
|
||||
# 1562| r1562_12(glval<int>) = CopyValue : r1562_8
|
||||
# 1562| r1562_13(int &) = CopyValue : r1562_12
|
||||
# 1562| mu1562_14(int &) = Store[i] : &:r1562_5, r1562_13
|
||||
# 1562| r1562_15(glval<double &>) = VariableAddress[d] :
|
||||
# 1562| r1562_16(glval<StructuredBindingTuple>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1562| r1562_17(glval<unknown>) = FunctionAddress[get] :
|
||||
# 1562| r1562_18(double &) = Call[get] : func:r1562_17, this:r1562_16
|
||||
# 1562| mu1562_19(unknown) = ^CallSideEffect : ~m?
|
||||
# 1562| v1562_20(void) = ^IndirectReadSideEffect[-1] : &:r1562_16, ~m?
|
||||
# 1562| mu1562_21(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1562_16
|
||||
# 1562| r1562_22(glval<double>) = CopyValue : r1562_18
|
||||
# 1562| r1562_23(double &) = CopyValue : r1562_22
|
||||
# 1562| mu1562_24(double &) = Store[d] : &:r1562_15, r1562_23
|
||||
# 1562| r1562_25(glval<int &>) = VariableAddress[r] :
|
||||
# 1562| r1562_26(glval<StructuredBindingTuple>) = VariableAddress[(unnamed local variable)] :
|
||||
# 1562| r1562_27(glval<unknown>) = FunctionAddress[get] :
|
||||
# 1562| r1562_28(int &) = Call[get] : func:r1562_27, this:r1562_26
|
||||
# 1562| mu1562_29(unknown) = ^CallSideEffect : ~m?
|
||||
# 1562| v1562_30(void) = ^IndirectReadSideEffect[-1] : &:r1562_26, ~m?
|
||||
# 1562| mu1562_31(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1562_26
|
||||
# 1562| r1562_32(glval<int>) = CopyValue : r1562_28
|
||||
# 1562| r1562_33(int &) = CopyValue : r1562_32
|
||||
# 1562| mu1562_34(int &) = Store[r] : &:r1562_25, r1562_33
|
||||
# 1563| r1563_1(double) = Constant[4.0] :
|
||||
# 1563| r1563_2(glval<double &>) = VariableAddress[d] :
|
||||
# 1563| r1563_3(double &) = Load[d] : &:r1563_2, ~m?
|
||||
# 1563| r1563_4(glval<double>) = CopyValue : r1563_3
|
||||
# 1563| mu1563_5(double) = Store[?] : &:r1563_4, r1563_1
|
||||
# 1564| r1564_1(glval<double &>) = VariableAddress[rd] :
|
||||
# 1564| r1564_2(glval<double &>) = VariableAddress[d] :
|
||||
# 1564| r1564_3(double &) = Load[d] : &:r1564_2, ~m?
|
||||
# 1564| r1564_4(glval<double>) = CopyValue : r1564_3
|
||||
# 1564| r1564_5(double &) = CopyValue : r1564_4
|
||||
# 1564| mu1564_6(double &) = Store[rd] : &:r1564_1, r1564_5
|
||||
# 1565| r1565_1(glval<int>) = VariableAddress[v] :
|
||||
# 1565| r1565_2(glval<int &>) = VariableAddress[i] :
|
||||
# 1565| r1565_3(int &) = Load[i] : &:r1565_2, ~m?
|
||||
# 1565| r1565_4(int) = Load[?] : &:r1565_3, ~m?
|
||||
# 1565| mu1565_5(int) = Store[v] : &:r1565_1, r1565_4
|
||||
# 1566| r1566_1(int) = Constant[5] :
|
||||
# 1566| r1566_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1566| r1566_3(int &) = Load[r] : &:r1566_2, ~m?
|
||||
# 1566| r1566_4(glval<int>) = CopyValue : r1566_3
|
||||
# 1566| mu1566_5(int) = Store[?] : &:r1566_4, r1566_1
|
||||
# 1567| r1567_1(glval<int &>) = VariableAddress[rr] :
|
||||
# 1567| r1567_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1567| r1567_3(int &) = Load[r] : &:r1567_2, ~m?
|
||||
# 1567| r1567_4(glval<int>) = CopyValue : r1567_3
|
||||
# 1567| r1567_5(int &) = CopyValue : r1567_4
|
||||
# 1567| mu1567_6(int &) = Store[rr] : &:r1567_1, r1567_5
|
||||
# 1568| r1568_1(glval<int>) = VariableAddress[w] :
|
||||
# 1568| r1568_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1568| r1568_3(int &) = Load[r] : &:r1568_2, ~m?
|
||||
# 1568| r1568_4(int) = Load[?] : &:r1568_3, ~m?
|
||||
# 1568| mu1568_5(int) = Store[w] : &:r1568_1, r1568_4
|
||||
# 1572| r1572_1(glval<StructuredBindingTuple>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1572| r1572_2(glval<StructuredBindingTuple>) = VariableAddress[t] :
|
||||
# 1572| r1572_3(StructuredBindingTuple) = Load[t] : &:r1572_2, ~m?
|
||||
# 1572| mu1572_4(StructuredBindingTuple) = Store[unnamed_local_variable] : &:r1572_1, r1572_3
|
||||
# 1573| r1573_1(glval<int &>) = VariableAddress[i] :
|
||||
# 1573| r1573_2(glval<StructuredBindingTuple>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1573| r1573_3(glval<unknown>) = FunctionAddress[get] :
|
||||
# 1573| r1573_4(int &) = Call[get] : func:r1573_3, this:r1573_2
|
||||
# 1573| mu1573_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 1573| v1573_6(void) = ^IndirectReadSideEffect[-1] : &:r1573_2, ~m?
|
||||
# 1573| mu1573_7(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1573_2
|
||||
# 1573| r1573_8(glval<int>) = CopyValue : r1573_4
|
||||
# 1573| r1573_9(int &) = CopyValue : r1573_8
|
||||
# 1573| mu1573_10(int &) = Store[i] : &:r1573_1, r1573_9
|
||||
# 1574| r1574_1(glval<double &>) = VariableAddress[d] :
|
||||
# 1574| r1574_2(glval<StructuredBindingTuple>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1574| r1574_3(glval<unknown>) = FunctionAddress[get] :
|
||||
# 1574| r1574_4(double &) = Call[get] : func:r1574_3, this:r1574_2
|
||||
# 1574| mu1574_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 1574| v1574_6(void) = ^IndirectReadSideEffect[-1] : &:r1574_2, ~m?
|
||||
# 1574| mu1574_7(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1574_2
|
||||
# 1574| r1574_8(glval<double>) = CopyValue : r1574_4
|
||||
# 1574| r1574_9(double &) = CopyValue : r1574_8
|
||||
# 1574| mu1574_10(double &) = Store[d] : &:r1574_1, r1574_9
|
||||
# 1575| r1575_1(glval<int &>) = VariableAddress[r] :
|
||||
# 1575| r1575_2(glval<StructuredBindingTuple>) = VariableAddress[unnamed_local_variable] :
|
||||
# 1575| r1575_3(glval<unknown>) = FunctionAddress[get] :
|
||||
# 1575| r1575_4(int &) = Call[get] : func:r1575_3, this:r1575_2
|
||||
# 1575| mu1575_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 1575| v1575_6(void) = ^IndirectReadSideEffect[-1] : &:r1575_2, ~m?
|
||||
# 1575| mu1575_7(StructuredBindingTuple) = ^IndirectMayWriteSideEffect[-1] : &:r1575_2
|
||||
# 1575| r1575_8(glval<int>) = CopyValue : r1575_4
|
||||
# 1575| r1575_9(int &) = CopyValue : r1575_8
|
||||
# 1575| mu1575_10(int &) = Store[r] : &:r1575_1, r1575_9
|
||||
# 1576| r1576_1(double) = Constant[4.0] :
|
||||
# 1576| r1576_2(glval<double &>) = VariableAddress[d] :
|
||||
# 1576| r1576_3(double &) = Load[d] : &:r1576_2, ~m?
|
||||
# 1576| r1576_4(glval<double>) = CopyValue : r1576_3
|
||||
# 1576| mu1576_5(double) = Store[?] : &:r1576_4, r1576_1
|
||||
# 1577| r1577_1(glval<double &>) = VariableAddress[rd] :
|
||||
# 1577| r1577_2(glval<double &>) = VariableAddress[d] :
|
||||
# 1577| r1577_3(double &) = Load[d] : &:r1577_2, ~m?
|
||||
# 1577| r1577_4(glval<double>) = CopyValue : r1577_3
|
||||
# 1577| r1577_5(double &) = CopyValue : r1577_4
|
||||
# 1577| mu1577_6(double &) = Store[rd] : &:r1577_1, r1577_5
|
||||
# 1578| r1578_1(glval<int>) = VariableAddress[v] :
|
||||
# 1578| r1578_2(glval<int &>) = VariableAddress[i] :
|
||||
# 1578| r1578_3(int &) = Load[i] : &:r1578_2, ~m?
|
||||
# 1578| r1578_4(int) = Load[?] : &:r1578_3, ~m?
|
||||
# 1578| mu1578_5(int) = Store[v] : &:r1578_1, r1578_4
|
||||
# 1579| r1579_1(int) = Constant[5] :
|
||||
# 1579| r1579_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1579| r1579_3(int &) = Load[r] : &:r1579_2, ~m?
|
||||
# 1579| r1579_4(glval<int>) = CopyValue : r1579_3
|
||||
# 1579| mu1579_5(int) = Store[?] : &:r1579_4, r1579_1
|
||||
# 1580| r1580_1(glval<int &>) = VariableAddress[rr] :
|
||||
# 1580| r1580_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1580| r1580_3(int &) = Load[r] : &:r1580_2, ~m?
|
||||
# 1580| r1580_4(glval<int>) = CopyValue : r1580_3
|
||||
# 1580| r1580_5(int &) = CopyValue : r1580_4
|
||||
# 1580| mu1580_6(int &) = Store[rr] : &:r1580_1, r1580_5
|
||||
# 1581| r1581_1(glval<int>) = VariableAddress[w] :
|
||||
# 1581| r1581_2(glval<int &>) = VariableAddress[r] :
|
||||
# 1581| r1581_3(int &) = Load[r] : &:r1581_2, ~m?
|
||||
# 1581| r1581_4(int) = Load[?] : &:r1581_3, ~m?
|
||||
# 1581| mu1581_5(int) = Store[w] : &:r1581_1, r1581_4
|
||||
# 1583| v1583_1(void) = NoOp :
|
||||
# 1558| v1558_4(void) = ReturnVoid :
|
||||
# 1558| v1558_5(void) = AliasedUse : ~m?
|
||||
# 1558| v1558_6(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in network request
|
||||
* @description Sending network requests with user-controlled data allows for request forgery attacks.
|
||||
* @name Server-side request forgery
|
||||
* @description Making a network request with user-controlled data in the URL allows for request forgery attacks.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
|
||||
19
java/ql/src/experimental/Security/CWE/CWE-094/SSTIBad.java
Normal file
19
java/ql/src/experimental/Security/CWE/CWE-094/SSTIBad.java
Normal file
@@ -0,0 +1,19 @@
|
||||
@Controller
|
||||
public class VelocitySSTI {
|
||||
|
||||
@GetMapping(value = "bad")
|
||||
public void bad(HttpServletRequest request) {
|
||||
Velocity.init();
|
||||
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = new VelocityContext();
|
||||
|
||||
context.put("name", "Velocity");
|
||||
context.put("project", "Jakarta");
|
||||
|
||||
StringWriter w = new StringWriter();
|
||||
// evaluate( Context context, Writer out, String logTag, String instring )
|
||||
Velocity.evaluate(context, w, "mystring", code);
|
||||
}
|
||||
}
|
||||
17
java/ql/src/experimental/Security/CWE/CWE-094/SSTIGood.java
Normal file
17
java/ql/src/experimental/Security/CWE/CWE-094/SSTIGood.java
Normal file
@@ -0,0 +1,17 @@
|
||||
@Controller
|
||||
public class VelocitySSTI {
|
||||
|
||||
@GetMapping(value = "good")
|
||||
public void good(HttpServletRequest request) {
|
||||
Velocity.init();
|
||||
VelocityContext context = new VelocityContext();
|
||||
|
||||
context.put("name", "Velocity");
|
||||
context.put("project", "Jakarta");
|
||||
|
||||
String s = "We are using $project $name to render this.";
|
||||
StringWriter w = new StringWriter();
|
||||
Velocity.evaluate(context, w, "mystring", s);
|
||||
System.out.println(" string : " + w);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Template Injection occurs when user input is embedded in a template in an unsafe manner.
|
||||
An attacker can use native template syntax to inject a malicious payload into a template, which is then executed server-side. This permits the attacker to run arbitrary code in the server's context.</p>
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>
|
||||
To fix this, ensure that an untrusted value is not used as a template. If the application requirements do not allow this, use a sandboxed environment where access to unsafe attributes and methods is prohibited.
|
||||
</p>
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>
|
||||
In the example given below, an untrusted HTTP parameter
|
||||
<code>code</code>
|
||||
is used as a Velocity template string. This can lead to remote code execution.
|
||||
</p>
|
||||
<sample src="SSTIBad.java" />
|
||||
|
||||
<p>
|
||||
In the next example the problem is avoided by using a fixed template string
|
||||
<code>s</code>
|
||||
. Since, the template is not attacker controlled in this case, we prevent untrusted code execution.
|
||||
</p>
|
||||
<sample src="SSTIGood.java" />
|
||||
</example>
|
||||
<references>
|
||||
<li>Portswigger : [Server Side Template Injection](https://portswigger.net/web-security/server-side-template-injection)</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @name Server Side Template Injection
|
||||
* @description Untrusted input used as a template parameter can lead to remote code execution.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/server-side-template-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-094
|
||||
*/
|
||||
|
||||
import java
|
||||
import TemplateInjection
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from TemplateInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Potential arbitrary code execution due to $@.",
|
||||
source.getNode(), "a template value loaded from a remote source."
|
||||
@@ -0,0 +1,209 @@
|
||||
/** Definitions related to the Server Side Template Injection (SSTI) query. */
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import experimental.semmle.code.java.frameworks.FreeMarker
|
||||
import experimental.semmle.code.java.frameworks.Velocity
|
||||
import experimental.semmle.code.java.frameworks.JinJava
|
||||
import experimental.semmle.code.java.frameworks.Pebble
|
||||
import experimental.semmle.code.java.frameworks.Thymeleaf
|
||||
|
||||
/** A taint tracking configuration to reason about Server Side Template Injection (SSTI) vulnerabilities */
|
||||
class TemplateInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
TemplateInjectionFlowConfig() { this = "TemplateInjectionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ) {
|
||||
exists(AdditionalFlowStep a | a.isAdditionalTaintStep(prev, succ))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink for Server Side Template Injection (SSTI) vulnerabilities
|
||||
*/
|
||||
abstract private class Sink extends DataFlow::ExprNode { }
|
||||
|
||||
/**
|
||||
* A data flow step for Server Side Template Injection (SSTI) vulnerabilities
|
||||
*/
|
||||
private class AdditionalFlowStep extends Unit {
|
||||
abstract predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to FreeMarker template engine's `process` method call.
|
||||
*/
|
||||
private class FreeMarkerProcessSink extends Sink {
|
||||
FreeMarkerProcessSink() {
|
||||
exists(MethodAccess m |
|
||||
m.getCallee() instanceof MethodFreeMarkerTemplateProcess and
|
||||
m.getArgument(0) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An reader passed an argument to FreeMarker template engine's `Template`
|
||||
* construtor call.
|
||||
*/
|
||||
private class FreeMarkerConstructorSink extends Sink {
|
||||
FreeMarkerConstructorSink() {
|
||||
// Template(java.lang.String name, java.io.Reader reader)
|
||||
// Template(java.lang.String name, java.io.Reader reader, Configuration cfg)
|
||||
// Template(java.lang.String name, java.io.Reader reader, Configuration cfg, java.lang.String encoding)
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader reader, Configuration cfg)
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader reader, Configuration cfg, ParserConfiguration customParserConfiguration, java.lang.String encoding)
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader reader, Configuration cfg, java.lang.String encoding)
|
||||
exists(ConstructorCall cc, Expr e |
|
||||
cc.getConstructor().getDeclaringType() instanceof TypeFreeMarkerTemplate and
|
||||
e = cc.getAnArgument() and
|
||||
(
|
||||
e.getType().(RefType).hasQualifiedName("java.io", "Reader") and
|
||||
this.asExpr() = e
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(ConstructorCall cc |
|
||||
cc.getConstructor().getDeclaringType() instanceof TypeFreeMarkerTemplate and
|
||||
// Template(java.lang.String name, java.lang.String sourceCode, Configuration cfg)
|
||||
cc.getNumArgument() = 3 and
|
||||
cc.getArgument(1).getType() instanceof TypeString and
|
||||
this.asExpr() = cc.getArgument(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to FreeMarker template engine's `putTemplate` method call.
|
||||
*/
|
||||
private class FreeMarkerStringTemplateLoaderPutTemplateSink extends Sink {
|
||||
FreeMarkerStringTemplateLoaderPutTemplateSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(1) and
|
||||
ma.getMethod() instanceof MethodFreeMarkerStringTemplateLoaderPutTemplate
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Pebble template engine's `getLiteralTemplate` or `getTemplate` method call.
|
||||
*/
|
||||
private class PebbleGetTemplateSinkTemplateSink extends Sink {
|
||||
PebbleGetTemplateSinkTemplateSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
ma.getMethod() instanceof MethodPebbleGetTemplate
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to JinJava template engine's `render` or `renderForResult` method call.
|
||||
*/
|
||||
private class JinjavaRenderSink extends Sink {
|
||||
JinjavaRenderSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
(
|
||||
ma.getMethod() instanceof MethodJinjavaRenderForResult
|
||||
or
|
||||
ma.getMethod() instanceof MethodJinjavaRender
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to ThymeLeaf template engine's `process` method call.
|
||||
*/
|
||||
private class ThymeLeafRenderSink extends Sink {
|
||||
ThymeLeafRenderSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
ma.getMethod() instanceof MethodThymeleafProcess
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tainted data flowing into a Velocity Context through `put` method taints the context.
|
||||
*/
|
||||
private class VelocityContextFlow extends AdditionalFlowStep {
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ) {
|
||||
exists(MethodAccess m | m.getMethod() instanceof MethodVelocityContextPut |
|
||||
m.getArgument(1) = prev.asExpr() and
|
||||
succ.asExpr() = m.getQualifier()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `mergeTemplate` method call.
|
||||
*/
|
||||
private class VelocityMergeTempSink extends Sink {
|
||||
VelocityMergeTempSink() {
|
||||
exists(MethodAccess m |
|
||||
// static boolean mergeTemplate(String templateName, String encoding, Context context, Writer writer)
|
||||
m.getCallee() instanceof MethodVelocityMergeTemplate and
|
||||
m.getArgument(2) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `mergeTemplate` method call.
|
||||
*/
|
||||
private class VelocityMergeSink extends Sink {
|
||||
VelocityMergeSink() {
|
||||
exists(MethodAccess m |
|
||||
m.getCallee() instanceof MethodVelocityMerge and
|
||||
// public void merge(Context context, Writer writer)
|
||||
// public void merge(Context context, Writer writer, List<String> macroLibraries)
|
||||
m.getArgument(0) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `evaluate` method call.
|
||||
*/
|
||||
private class VelocityEvaluateSink extends Sink {
|
||||
VelocityEvaluateSink() {
|
||||
exists(MethodAccess m |
|
||||
m.getCallee() instanceof MethodVelocityEvaluate and
|
||||
m.getArgument([0, 3]) = this.getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `parse` method call.
|
||||
*/
|
||||
private class VelocityParseSink extends Sink {
|
||||
VelocityParseSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(0) and
|
||||
ma.getMethod() instanceof MethodVelocityParse
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to Velocity template engine's `putStringResource` method call.
|
||||
*/
|
||||
private class VelocityPutStringResSink extends Sink {
|
||||
VelocityPutStringResSink() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getArgument(1) and
|
||||
ma.getMethod() instanceof MethodVelocityPutStringResource
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
import java
|
||||
import UnsafeUrlForward
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import experimental.semmle.code.java.PathSanitizer
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class UnsafeUrlForwardFlowConfig extends TaintTracking::Configuration {
|
||||
@@ -35,7 +35,7 @@ class UnsafeUrlForwardFlowConfig extends TaintTracking::Configuration {
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof UnsafeUrlForwardSanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof UnsafeUrlForwardBarrierGuard
|
||||
guard instanceof PathTraversalBarrierGuard
|
||||
}
|
||||
|
||||
override DataFlow::FlowFeature getAFeature() {
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import java
|
||||
import DataFlow
|
||||
import semmle.code.java.controlflow.Guards
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.Servlets
|
||||
import semmle.code.java.frameworks.spring.SpringWeb
|
||||
import semmle.code.java.security.RequestForgery
|
||||
private import semmle.code.java.dataflow.StringPrefixes
|
||||
|
||||
/** A sink for unsafe URL forward vulnerabilities. */
|
||||
@@ -13,9 +8,6 @@ abstract class UnsafeUrlForwardSink extends DataFlow::Node { }
|
||||
/** A sanitizer for unsafe URL forward vulnerabilities. */
|
||||
abstract class UnsafeUrlForwardSanitizer extends DataFlow::Node { }
|
||||
|
||||
/** A barrier guard that protects against URL forward vulnerabilities. */
|
||||
abstract class UnsafeUrlForwardBarrierGuard extends DataFlow::BarrierGuard { }
|
||||
|
||||
/** An argument to `getRequestDispatcher`. */
|
||||
private class RequestDispatcherSink extends UnsafeUrlForwardSink {
|
||||
RequestDispatcherSink() {
|
||||
@@ -59,175 +51,6 @@ private class FollowsSanitizingPrefix extends UnsafeUrlForwardSanitizer {
|
||||
FollowsSanitizingPrefix() { this.asExpr() = any(SanitizingPrefix fp).getAnAppendedExpression() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that considers safe a string being exactly compared to a trusted value.
|
||||
*/
|
||||
private class ExactStringPathMatchGuard extends UnsafeUrlForwardBarrierGuard instanceof MethodAccess {
|
||||
ExactStringPathMatchGuard() {
|
||||
super.getMethod().getDeclaringType() instanceof TypeString and
|
||||
super.getMethod().getName() = ["equals", "equalsIgnoreCase"]
|
||||
}
|
||||
|
||||
override predicate checks(Expr e, boolean branch) {
|
||||
e = super.getQualifier() and
|
||||
branch = true
|
||||
}
|
||||
}
|
||||
|
||||
private class AllowListGuard extends Guard instanceof MethodAccess {
|
||||
AllowListGuard() {
|
||||
(isStringPartialMatch(this) or isPathPartialMatch(this)) and
|
||||
not isDisallowedWord(super.getAnArgument())
|
||||
}
|
||||
|
||||
Expr getCheckedExpr() { result = super.getQualifier() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that considers a path safe because it is checked against an allowlist of partial trusted values.
|
||||
* This requires additional protection against path traversal, either another guard (`PathTraversalGuard`)
|
||||
* or a sanitizer (`PathNormalizeSanitizer`), to ensure any internal `..` components are removed from the path.
|
||||
*/
|
||||
private class AllowListBarrierGuard extends UnsafeUrlForwardBarrierGuard instanceof AllowListGuard {
|
||||
override predicate checks(Expr e, boolean branch) {
|
||||
e = super.getCheckedExpr() and
|
||||
branch = true and
|
||||
(
|
||||
// Either a path normalization sanitizer comes before the guard,
|
||||
exists(PathNormalizeSanitizer sanitizer | DataFlow::localExprFlow(sanitizer, e))
|
||||
or
|
||||
// or a check like `!path.contains("..")` comes before the guard
|
||||
exists(PathTraversalGuard previousGuard |
|
||||
DataFlow::localExprFlow(previousGuard.getCheckedExpr(), e) and
|
||||
previousGuard.controls(this.getBasicBlock().(ConditionBlock), false)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that considers a path safe because it is checked for `..` components, having previously
|
||||
* been checked for a trusted prefix.
|
||||
*/
|
||||
private class DotDotCheckBarrierGuard extends UnsafeUrlForwardBarrierGuard instanceof PathTraversalGuard {
|
||||
override predicate checks(Expr e, boolean branch) {
|
||||
e = super.getCheckedExpr() and
|
||||
branch = false and
|
||||
// The same value has previously been checked against a list of allowed prefixes:
|
||||
exists(AllowListGuard previousGuard |
|
||||
DataFlow::localExprFlow(previousGuard.getCheckedExpr(), e) and
|
||||
previousGuard.controls(this.getBasicBlock().(ConditionBlock), true)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class BlockListGuard extends Guard instanceof MethodAccess {
|
||||
BlockListGuard() {
|
||||
(isStringPartialMatch(this) or isPathPartialMatch(this)) and
|
||||
isDisallowedWord(super.getAnArgument())
|
||||
}
|
||||
|
||||
Expr getCheckedExpr() { result = super.getQualifier() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that considers a string safe because it is checked against a blocklist of known dangerous values.
|
||||
* This requires a prior check for URL encoding concealing a forbidden value, either a guard (`UrlEncodingGuard`)
|
||||
* or a sanitizer (`UrlDecodeSanitizer`).
|
||||
*/
|
||||
private class BlockListBarrierGuard extends UnsafeUrlForwardBarrierGuard instanceof BlockListGuard {
|
||||
override predicate checks(Expr e, boolean branch) {
|
||||
e = super.getCheckedExpr() and
|
||||
branch = false and
|
||||
(
|
||||
// Either `e` has been URL decoded:
|
||||
exists(UrlDecodeSanitizer sanitizer | DataFlow::localExprFlow(sanitizer, e))
|
||||
or
|
||||
// or `e` has previously been checked for URL encoding sequences:
|
||||
exists(UrlEncodingGuard previousGuard |
|
||||
DataFlow::localExprFlow(previousGuard.getCheckedExpr(), e) and
|
||||
previousGuard.controls(this.getBasicBlock(), false)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that considers a string safe because it is checked for URL encoding sequences,
|
||||
* having previously been checked against a block-list of forbidden values.
|
||||
*/
|
||||
private class URLEncodingBarrierGuard extends UnsafeUrlForwardBarrierGuard instanceof UrlEncodingGuard {
|
||||
override predicate checks(Expr e, boolean branch) {
|
||||
e = super.getCheckedExpr() and
|
||||
branch = false and
|
||||
exists(BlockListGuard previousGuard |
|
||||
DataFlow::localExprFlow(previousGuard.getCheckedExpr(), e) and
|
||||
previousGuard.controls(this.getBasicBlock(), false)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` is a call to a method that checks a partial string match.
|
||||
*/
|
||||
private predicate isStringPartialMatch(MethodAccess ma) {
|
||||
ma.getMethod().getDeclaringType() instanceof TypeString and
|
||||
ma.getMethod().getName() =
|
||||
["contains", "startsWith", "matches", "regionMatches", "indexOf", "lastIndexOf"]
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ma` is a call to a method of `java.nio.file.Path` that checks a partial path match.
|
||||
*/
|
||||
private predicate isPathPartialMatch(MethodAccess ma) {
|
||||
ma.getMethod().getDeclaringType() instanceof TypePath and
|
||||
ma.getMethod().getName() = "startsWith"
|
||||
}
|
||||
|
||||
private predicate isDisallowedWord(CompileTimeConstantExpr word) {
|
||||
word.getStringValue().matches(["%WEB-INF%", "%META-INF%", "%..%"])
|
||||
}
|
||||
|
||||
/** A complementary guard that protects against path traversal, by looking for the literal `..`. */
|
||||
private class PathTraversalGuard extends Guard instanceof MethodAccess {
|
||||
Expr checked;
|
||||
|
||||
PathTraversalGuard() {
|
||||
super.getMethod().getDeclaringType() instanceof TypeString and
|
||||
super.getMethod().hasName(["contains", "indexOf"]) and
|
||||
super.getAnArgument().(CompileTimeConstantExpr).getStringValue() = ".."
|
||||
}
|
||||
|
||||
Expr getCheckedExpr() { result = super.getQualifier() }
|
||||
}
|
||||
|
||||
/** A complementary sanitizer that protects against path traversal using path normalization. */
|
||||
private class PathNormalizeSanitizer extends MethodAccess {
|
||||
PathNormalizeSanitizer() {
|
||||
this.getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Path") and
|
||||
this.getMethod().hasName("normalize")
|
||||
}
|
||||
}
|
||||
|
||||
/** A complementary guard that protects against double URL encoding, by looking for the literal `%`. */
|
||||
private class UrlEncodingGuard extends Guard instanceof MethodAccess {
|
||||
UrlEncodingGuard() {
|
||||
super.getMethod().getDeclaringType() instanceof TypeString and
|
||||
super.getMethod().hasName(["contains", "indexOf"]) and
|
||||
super.getAnArgument().(CompileTimeConstantExpr).getStringValue() = "%"
|
||||
}
|
||||
|
||||
Expr getCheckedExpr() { result = super.getQualifier() }
|
||||
}
|
||||
|
||||
/** A complementary sanitizer that protects against double URL encoding using URL decoding. */
|
||||
private class UrlDecodeSanitizer extends MethodAccess {
|
||||
UrlDecodeSanitizer() {
|
||||
this.getMethod().getDeclaringType().hasQualifiedName("java.net", "URLDecoder") and
|
||||
this.getMethod().hasName("decode")
|
||||
}
|
||||
}
|
||||
|
||||
private class ForwardPrefix extends InterestingPrefix {
|
||||
ForwardPrefix() { this.getStringValue() = "forward:" }
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/** Definitions related to the FreeMarker Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `Template` class of the FreeMarker Template Engine */
|
||||
class TypeFreeMarkerTemplate extends Class {
|
||||
TypeFreeMarkerTemplate() { this.hasQualifiedName("freemarker.template", "Template") }
|
||||
}
|
||||
|
||||
/** The `process` method of the FreeMarker Template Engine's `Template` class */
|
||||
class MethodFreeMarkerTemplateProcess extends Method {
|
||||
MethodFreeMarkerTemplateProcess() {
|
||||
this.getDeclaringType() instanceof TypeFreeMarkerTemplate and
|
||||
this.hasName("process")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `StringTemplateLoader` class of the FreeMarker Template Engine */
|
||||
class TypeFreeMarkerStringLoader extends Class {
|
||||
TypeFreeMarkerStringLoader() { this.hasQualifiedName("freemarker.cache", "StringTemplateLoader") }
|
||||
}
|
||||
|
||||
/** The `process` method of the FreeMarker Template Engine's `StringTemplateLoader` class */
|
||||
class MethodFreeMarkerStringTemplateLoaderPutTemplate extends Method {
|
||||
MethodFreeMarkerStringTemplateLoaderPutTemplate() {
|
||||
this.getDeclaringType() instanceof TypeFreeMarkerStringLoader and
|
||||
this.hasName("putTemplate")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/** Definitions related to the Jinjava Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `Jinjava` class of the Jinjava Templating Engine. */
|
||||
class TypeJinjava extends Class {
|
||||
TypeJinjava() { this.hasQualifiedName("com.hubspot.jinjava", "Jinjava") }
|
||||
}
|
||||
|
||||
/** The `render` method of the Jinjava Templating Engine. */
|
||||
class MethodJinjavaRender extends Method {
|
||||
MethodJinjavaRender() {
|
||||
this.getDeclaringType() instanceof TypeJinjava and
|
||||
this.hasName("render")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `render` method of the Jinjava Templating Engine. */
|
||||
class MethodJinjavaRenderForResult extends Method {
|
||||
MethodJinjavaRenderForResult() {
|
||||
this.getDeclaringType() instanceof TypeJinjava and
|
||||
this.hasName("renderForResult")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/** Definitions related to the Pebble Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `PebbleEngine` class of the Pebble Templating Engine. */
|
||||
class TypePebbleEngine extends Class {
|
||||
TypePebbleEngine() { this.hasQualifiedName("com.mitchellbosecke.pebble", "PebbleEngine") }
|
||||
}
|
||||
|
||||
/** The `getTemplate` method of the Pebble Templating Engine. */
|
||||
class MethodPebbleGetTemplate extends Method {
|
||||
MethodPebbleGetTemplate() {
|
||||
this.getDeclaringType() instanceof TypePebbleEngine and
|
||||
this.hasName(["getTemplate", "getLiteralTemplate"])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/** Definitions related to the Thymeleaf Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/**
|
||||
* A class implementing the `ITemplateEngine` interface of the Thymeleaf
|
||||
* Templating Engine such as the `TemplateEngine` class.
|
||||
*/
|
||||
class TypeThymeleafTemplateEngine extends Class {
|
||||
TypeThymeleafTemplateEngine() {
|
||||
this.hasQualifiedName("org.thymeleaf", "TemplateEngine")
|
||||
or
|
||||
exists(Type t | this.getASupertype*().extendsOrImplements(t) |
|
||||
t.hasName("org.thymeleaf.ITemplateEngine")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `process` or `processThrottled` method of the Thymeleaf Templating Engine. */
|
||||
class MethodThymeleafProcess extends Method {
|
||||
MethodThymeleafProcess() {
|
||||
this.getDeclaringType() instanceof TypeThymeleafTemplateEngine and
|
||||
this.hasName(["process", "processThrottled"])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/** Definitions related to the Apache Velocity Templating library. */
|
||||
|
||||
import java
|
||||
|
||||
/** The `org.apache.velocity.context.AbstractContext` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityAbstractContext extends Class {
|
||||
TypeVelocityAbstractContext() {
|
||||
this.hasQualifiedName("org.apache.velocity.context", "AbstractContext")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.runtime.RuntimeServices` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityRuntimeRuntimeServices extends Class {
|
||||
TypeVelocityRuntimeRuntimeServices() {
|
||||
this.hasQualifiedName("org.apache.velocity.runtime", "RuntimeServices")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.Template` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityTemplate extends Class {
|
||||
TypeVelocityTemplate() { this.hasQualifiedName("org.apache.velocity", "Template") }
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.runtime.RuntimeSingleton` classTemplating Engine. */
|
||||
class TypeVelocityRuntimeRuntimeSingleton extends Class {
|
||||
TypeVelocityRuntimeRuntimeSingleton() {
|
||||
this.hasQualifiedName("org.apache.velocity.runtime", "RuntimeSingleton")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.VelocityEngine` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityVelocityEngine extends Class {
|
||||
TypeVelocityVelocityEngine() { this.hasQualifiedName("org.apache.velocity", "VelocityEngine") }
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.app.VelocityEngine` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityAppVelocityEngine extends RefType {
|
||||
TypeVelocityAppVelocityEngine() {
|
||||
this.hasQualifiedName("org.apache.velocity.app", "VelocityEngine")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `org.apache.velocity.app.Velocity` class of the Velocity Templating Engine. */
|
||||
class TypeVelocityAppVelocity extends RefType {
|
||||
TypeVelocityAppVelocity() { this.hasQualifiedName("org.apache.velocity.app", "Velocity") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `org.apache.velocity.runtime.resource.util.StringResourceRepository` interface
|
||||
* of the Velocity Templating Engine.
|
||||
*/
|
||||
class TypeVelocityStringResourceRepo extends RefType {
|
||||
TypeVelocityStringResourceRepo() {
|
||||
this.hasQualifiedName("org.apache.velocity.runtime.resource.util", "StringResourceRepository")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `internalPut` and `put` methods of the Velocity Templating Engine. */
|
||||
class MethodVelocityContextPut extends Method {
|
||||
MethodVelocityContextPut() {
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityAbstractContext and
|
||||
this.hasName(["put", "internalPut"])
|
||||
}
|
||||
}
|
||||
|
||||
/** The `evaluate` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityEvaluate extends Method {
|
||||
MethodVelocityEvaluate() {
|
||||
// static boolean evaluate(Context context, Writer out, String logTag, String instring)
|
||||
// static boolean evaluate(Context context, Writer writer, String logTag, Reader reader)
|
||||
(
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocity or
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocityEngine or
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityRuntimeRuntimeServices
|
||||
) and
|
||||
this.hasName("evaluate")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `mergeTemplate` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityMergeTemplate extends Method {
|
||||
MethodVelocityMergeTemplate() {
|
||||
// static boolean mergeTemplate(String templateName, String encoding, Context context, Writer writer)
|
||||
(
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocity or
|
||||
this.getDeclaringType() instanceof TypeVelocityAppVelocityEngine
|
||||
) and
|
||||
this.hasName("mergeTemplate")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `merge` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityMerge extends Method {
|
||||
MethodVelocityMerge() {
|
||||
// void merge(Context context, Writer writer)
|
||||
// void merge(Context context, Writer writer, List<String> macroLibraries)
|
||||
this.getDeclaringType() instanceof TypeVelocityTemplate and
|
||||
this.hasName("merge")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `parse` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityParse extends Method {
|
||||
MethodVelocityParse() {
|
||||
(
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityRuntimeRuntimeSingleton or
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityRuntimeRuntimeServices
|
||||
) and
|
||||
this.hasName("parse")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `putStringResource` method of the Velocity Templating Engine. */
|
||||
class MethodVelocityPutStringResource extends Method {
|
||||
MethodVelocityPutStringResource() {
|
||||
this.getDeclaringType().getASupertype*() instanceof TypeVelocityStringResourceRepo and
|
||||
this.hasName("putStringResource")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.lang.String;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.HashMap;
|
||||
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.cache.StringTemplateLoader;
|
||||
import freemarker.template.ParserConfiguration;
|
||||
|
||||
@Controller
|
||||
public class FreemarkerSSTI {
|
||||
String sourceName = "sourceName";
|
||||
|
||||
@GetMapping(value = "bad1")
|
||||
public void bad1(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
Reader reader = new StringReader(code);
|
||||
|
||||
// Template(java.lang.String name, java.io.Reader reader)
|
||||
Template t = new Template(name, reader);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad2")
|
||||
public void bad2(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
Reader reader = new StringReader(code);
|
||||
Configuration cfg = new Configuration();
|
||||
|
||||
// Template(java.lang.String name, java.io.Reader reader, Configuration cfg)
|
||||
Template t = new Template(name, reader, cfg);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad3")
|
||||
public void bad3(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
Reader reader = new StringReader(code);
|
||||
Configuration cfg = new Configuration();
|
||||
|
||||
// Template(java.lang.String name, java.io.Reader reader, Configuration cfg,
|
||||
// java.lang.String encoding)
|
||||
Template t = new Template(name, reader, cfg, "UTF-8");
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad4")
|
||||
public void bad4(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String sourceCode = request.getParameter("sourceCode");
|
||||
Configuration cfg = new Configuration();
|
||||
|
||||
// Template(java.lang.String name, java.lang.String sourceCode, Configuration
|
||||
// cfg)
|
||||
Template t = new Template(name, sourceCode, cfg);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad5")
|
||||
public void bad5(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
Configuration cfg = new Configuration();
|
||||
Reader reader = new StringReader(code);
|
||||
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader
|
||||
// reader, Configuration cfg)
|
||||
Template t = new Template(name, sourceName, reader, cfg);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad6")
|
||||
public void bad6(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
Configuration cfg = new Configuration();
|
||||
ParserConfiguration customParserConfiguration = new Configuration();
|
||||
Reader reader = new StringReader(code);
|
||||
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader
|
||||
// reader, Configuration cfg, ParserConfiguration customParserConfiguration,
|
||||
// java.lang.String encoding)
|
||||
Template t = new Template(name, sourceName, reader, cfg, customParserConfiguration, "UTF-8");
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad7")
|
||||
public void bad7(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
Configuration cfg = new Configuration();
|
||||
ParserConfiguration customParserConfiguration = new Configuration();
|
||||
Reader reader = new StringReader(code);
|
||||
|
||||
// Template(java.lang.String name, java.lang.String sourceName, java.io.Reader
|
||||
// reader, Configuration cfg, java.lang.String encoding)
|
||||
Template t = new Template(name, sourceName, reader, cfg, "UTF-8");
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad8")
|
||||
public void bad8(HttpServletRequest request) {
|
||||
String code = request.getParameter("code");
|
||||
StringTemplateLoader stringLoader = new StringTemplateLoader();
|
||||
|
||||
// void putTemplate(java.lang.String name, java.lang.String templateContent)
|
||||
stringLoader.putTemplate("myTemplate", code);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad9")
|
||||
public void bad9(HttpServletRequest request) {
|
||||
String code = request.getParameter("code");
|
||||
StringTemplateLoader stringLoader = new StringTemplateLoader();
|
||||
|
||||
// void putTemplate(java.lang.String name, java.lang.String templateContent,
|
||||
// long lastModified)
|
||||
stringLoader.putTemplate("myTemplate", code, 0);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad10")
|
||||
public void bad10(HttpServletRequest request) {
|
||||
HashMap root = new HashMap();
|
||||
String code = request.getParameter("code");
|
||||
root.put("code", code);
|
||||
Configuration cfg = new Configuration();
|
||||
Template temp = cfg.getTemplate("test.ftlh");
|
||||
OutputStreamWriter out = new OutputStreamWriter(System.out);
|
||||
temp.process(root, out);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.lang.String;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.hubspot.jinjava.*;
|
||||
import com.hubspot.jinjava.JinjavaConfig;
|
||||
import com.hubspot.jinjava.interpret.*;
|
||||
|
||||
@Controller
|
||||
public class JinJavaSSTI {
|
||||
String sourceName = "sourceName";
|
||||
|
||||
@GetMapping(value = "bad1")
|
||||
public void bad1(HttpServletRequest request) {
|
||||
String template = request.getParameter("template");
|
||||
Jinjava jinjava = new Jinjava();
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
// String render(String template, Map<String, ?> bindings)
|
||||
String renderedTemplate = jinjava.render(template, context);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad2")
|
||||
public void bad2(HttpServletRequest request) {
|
||||
String template = request.getParameter("template");
|
||||
Jinjava jinjava = new Jinjava();
|
||||
Map<String, Object> bindings = new HashMap<>();
|
||||
// RenderResult renderForResult (String template, Map<String, ?> bindings)
|
||||
RenderResult renderResult = jinjava.renderForResult(template, bindings);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad3")
|
||||
public void bad3(HttpServletRequest request) {
|
||||
String template = request.getParameter("template");
|
||||
Jinjava jinjava = new Jinjava();
|
||||
Map<String, Object> bindings = new HashMap<>();
|
||||
JinjavaConfig renderConfig = new JinjavaConfig();
|
||||
|
||||
// RenderResult renderForResult (String template, Map<String, ?> bindings,
|
||||
// JinjavaConfig renderConfig)
|
||||
RenderResult renderResult = jinjava.renderForResult(template, bindings, renderConfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.lang.String;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import com.mitchellbosecke.pebble.PebbleEngine;
|
||||
import com.mitchellbosecke.pebble.template.*;
|
||||
|
||||
@Controller
|
||||
public class PebbleSSTI {
|
||||
String sourceName = "sourceName";
|
||||
|
||||
@GetMapping(value = "bad1")
|
||||
public void bad1(HttpServletRequest request) {
|
||||
String code = request.getParameter("code");
|
||||
PebbleEngine engine = new PebbleEngine.Builder().build();
|
||||
// public PebbleTemplate getTemplate(String templateName)
|
||||
PebbleTemplate compiledTemplate = engine.getTemplate(code);
|
||||
}
|
||||
@GetMapping(value = "bad2")
|
||||
public void bad2(HttpServletRequest request) {
|
||||
String code = request.getParameter("code");
|
||||
PebbleEngine engine = new PebbleEngine.Builder().build();
|
||||
// public PebbleTemplate getLiteralTemplate(String templateName)
|
||||
PebbleTemplate compiledTemplate = engine.getLiteralTemplate(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
edges
|
||||
| FreemarkerSSTI.java:23:17:23:44 | getParameter(...) : String | FreemarkerSSTI.java:24:36:24:39 | code : String |
|
||||
| FreemarkerSSTI.java:24:19:24:40 | new StringReader(...) : StringReader | FreemarkerSSTI.java:27:35:27:40 | reader |
|
||||
| FreemarkerSSTI.java:24:36:24:39 | code : String | FreemarkerSSTI.java:24:19:24:40 | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:33:17:33:44 | getParameter(...) : String | FreemarkerSSTI.java:34:36:34:39 | code : String |
|
||||
| FreemarkerSSTI.java:34:19:34:40 | new StringReader(...) : StringReader | FreemarkerSSTI.java:38:35:38:40 | reader |
|
||||
| FreemarkerSSTI.java:34:36:34:39 | code : String | FreemarkerSSTI.java:34:19:34:40 | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:44:17:44:44 | getParameter(...) : String | FreemarkerSSTI.java:45:36:45:39 | code : String |
|
||||
| FreemarkerSSTI.java:45:19:45:40 | new StringReader(...) : StringReader | FreemarkerSSTI.java:50:35:50:40 | reader |
|
||||
| FreemarkerSSTI.java:45:36:45:39 | code : String | FreemarkerSSTI.java:45:19:45:40 | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:56:23:56:56 | getParameter(...) : String | FreemarkerSSTI.java:61:35:61:44 | sourceCode |
|
||||
| FreemarkerSSTI.java:67:17:67:44 | getParameter(...) : String | FreemarkerSSTI.java:69:36:69:39 | code : String |
|
||||
| FreemarkerSSTI.java:69:19:69:40 | new StringReader(...) : StringReader | FreemarkerSSTI.java:73:47:73:52 | reader |
|
||||
| FreemarkerSSTI.java:69:36:69:39 | code : String | FreemarkerSSTI.java:69:19:69:40 | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:79:17:79:44 | getParameter(...) : String | FreemarkerSSTI.java:82:36:82:39 | code : String |
|
||||
| FreemarkerSSTI.java:82:19:82:40 | new StringReader(...) : StringReader | FreemarkerSSTI.java:87:47:87:52 | reader |
|
||||
| FreemarkerSSTI.java:82:36:82:39 | code : String | FreemarkerSSTI.java:82:19:82:40 | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:93:17:93:44 | getParameter(...) : String | FreemarkerSSTI.java:96:36:96:39 | code : String |
|
||||
| FreemarkerSSTI.java:96:19:96:40 | new StringReader(...) : StringReader | FreemarkerSSTI.java:100:47:100:52 | reader |
|
||||
| FreemarkerSSTI.java:96:36:96:39 | code : String | FreemarkerSSTI.java:96:19:96:40 | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:105:17:105:44 | getParameter(...) : String | FreemarkerSSTI.java:109:42:109:45 | code |
|
||||
| FreemarkerSSTI.java:114:17:114:44 | getParameter(...) : String | FreemarkerSSTI.java:119:42:119:45 | code |
|
||||
| FreemarkerSSTI.java:125:17:125:44 | getParameter(...) : String | FreemarkerSSTI.java:126:26:126:29 | code : String |
|
||||
| FreemarkerSSTI.java:126:9:126:12 | root [post update] [<map.value>] : String | FreemarkerSSTI.java:130:22:130:25 | root |
|
||||
| FreemarkerSSTI.java:126:26:126:29 | code : String | FreemarkerSSTI.java:126:9:126:12 | root [post update] [<map.value>] : String |
|
||||
| JinJavaSSTI.java:21:21:21:52 | getParameter(...) : String | JinJavaSSTI.java:25:44:25:51 | template |
|
||||
| JinJavaSSTI.java:30:21:30:52 | getParameter(...) : String | JinJavaSSTI.java:34:55:34:62 | template |
|
||||
| JinJavaSSTI.java:39:21:39:52 | getParameter(...) : String | JinJavaSSTI.java:46:55:46:62 | template |
|
||||
| PebbleSSTI.java:18:17:18:44 | getParameter(...) : String | PebbleSSTI.java:21:56:21:59 | code |
|
||||
| PebbleSSTI.java:25:17:25:44 | getParameter(...) : String | PebbleSSTI.java:28:63:28:66 | code |
|
||||
| ThymeleafSSTI.java:22:17:22:44 | getParameter(...) : String | ThymeleafSSTI.java:27:27:27:30 | code |
|
||||
| VelocitySSTI.java:31:17:31:44 | getParameter(...) : String | VelocitySSTI.java:38:45:38:48 | code |
|
||||
| VelocitySSTI.java:44:17:44:44 | getParameter(...) : String | VelocitySSTI.java:50:42:50:45 | code : String |
|
||||
| VelocitySSTI.java:50:25:50:46 | new StringReader(...) : StringReader | VelocitySSTI.java:53:45:53:50 | reader |
|
||||
| VelocitySSTI.java:50:42:50:45 | code : String | VelocitySSTI.java:50:25:50:46 | new StringReader(...) : StringReader |
|
||||
| VelocitySSTI.java:59:17:59:44 | getParameter(...) : String | VelocitySSTI.java:62:42:62:45 | code : String |
|
||||
| VelocitySSTI.java:62:25:62:46 | new StringReader(...) : StringReader | VelocitySSTI.java:63:25:63:30 | reader |
|
||||
| VelocitySSTI.java:62:42:62:45 | code : String | VelocitySSTI.java:62:25:62:46 | new StringReader(...) : StringReader |
|
||||
| VelocitySSTI.java:69:17:69:44 | getParameter(...) : String | VelocitySSTI.java:77:21:77:27 | context |
|
||||
| VelocitySSTI.java:83:17:83:44 | getParameter(...) : String | VelocitySSTI.java:89:60:89:66 | context |
|
||||
| VelocitySSTI.java:95:17:95:44 | getParameter(...) : String | VelocitySSTI.java:102:11:102:17 | context |
|
||||
| VelocitySSTI.java:108:17:108:44 | getParameter(...) : String | VelocitySSTI.java:115:11:115:17 | context |
|
||||
| VelocitySSTI.java:120:17:120:44 | getParameter(...) : String | VelocitySSTI.java:123:37:123:40 | code |
|
||||
nodes
|
||||
| FreemarkerSSTI.java:23:17:23:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:24:19:24:40 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:24:36:24:39 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:27:35:27:40 | reader | semmle.label | reader |
|
||||
| FreemarkerSSTI.java:33:17:33:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:34:19:34:40 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:34:36:34:39 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:38:35:38:40 | reader | semmle.label | reader |
|
||||
| FreemarkerSSTI.java:44:17:44:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:45:19:45:40 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:45:36:45:39 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:50:35:50:40 | reader | semmle.label | reader |
|
||||
| FreemarkerSSTI.java:56:23:56:56 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:61:35:61:44 | sourceCode | semmle.label | sourceCode |
|
||||
| FreemarkerSSTI.java:67:17:67:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:69:19:69:40 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:69:36:69:39 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:73:47:73:52 | reader | semmle.label | reader |
|
||||
| FreemarkerSSTI.java:79:17:79:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:82:19:82:40 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:82:36:82:39 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:87:47:87:52 | reader | semmle.label | reader |
|
||||
| FreemarkerSSTI.java:93:17:93:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:96:19:96:40 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| FreemarkerSSTI.java:96:36:96:39 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:100:47:100:52 | reader | semmle.label | reader |
|
||||
| FreemarkerSSTI.java:105:17:105:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:109:42:109:45 | code | semmle.label | code |
|
||||
| FreemarkerSSTI.java:114:17:114:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:119:42:119:45 | code | semmle.label | code |
|
||||
| FreemarkerSSTI.java:125:17:125:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| FreemarkerSSTI.java:126:9:126:12 | root [post update] [<map.value>] : String | semmle.label | root [post update] [<map.value>] : String |
|
||||
| FreemarkerSSTI.java:126:26:126:29 | code : String | semmle.label | code : String |
|
||||
| FreemarkerSSTI.java:130:22:130:25 | root | semmle.label | root |
|
||||
| JinJavaSSTI.java:21:21:21:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JinJavaSSTI.java:25:44:25:51 | template | semmle.label | template |
|
||||
| JinJavaSSTI.java:30:21:30:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JinJavaSSTI.java:34:55:34:62 | template | semmle.label | template |
|
||||
| JinJavaSSTI.java:39:21:39:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JinJavaSSTI.java:46:55:46:62 | template | semmle.label | template |
|
||||
| PebbleSSTI.java:18:17:18:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| PebbleSSTI.java:21:56:21:59 | code | semmle.label | code |
|
||||
| PebbleSSTI.java:25:17:25:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| PebbleSSTI.java:28:63:28:66 | code | semmle.label | code |
|
||||
| ThymeleafSSTI.java:22:17:22:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| ThymeleafSSTI.java:27:27:27:30 | code | semmle.label | code |
|
||||
| VelocitySSTI.java:31:17:31:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:38:45:38:48 | code | semmle.label | code |
|
||||
| VelocitySSTI.java:44:17:44:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:50:25:50:46 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| VelocitySSTI.java:50:42:50:45 | code : String | semmle.label | code : String |
|
||||
| VelocitySSTI.java:53:45:53:50 | reader | semmle.label | reader |
|
||||
| VelocitySSTI.java:59:17:59:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:62:25:62:46 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
||||
| VelocitySSTI.java:62:42:62:45 | code : String | semmle.label | code : String |
|
||||
| VelocitySSTI.java:63:25:63:30 | reader | semmle.label | reader |
|
||||
| VelocitySSTI.java:69:17:69:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:77:21:77:27 | context | semmle.label | context |
|
||||
| VelocitySSTI.java:83:17:83:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:89:60:89:66 | context | semmle.label | context |
|
||||
| VelocitySSTI.java:95:17:95:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:102:11:102:17 | context | semmle.label | context |
|
||||
| VelocitySSTI.java:108:17:108:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:115:11:115:17 | context | semmle.label | context |
|
||||
| VelocitySSTI.java:120:17:120:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| VelocitySSTI.java:123:37:123:40 | code | semmle.label | code |
|
||||
subpaths
|
||||
#select
|
||||
| FreemarkerSSTI.java:27:35:27:40 | reader | FreemarkerSSTI.java:23:17:23:44 | getParameter(...) : String | FreemarkerSSTI.java:27:35:27:40 | reader | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:23:17:23:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:38:35:38:40 | reader | FreemarkerSSTI.java:33:17:33:44 | getParameter(...) : String | FreemarkerSSTI.java:38:35:38:40 | reader | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:33:17:33:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:50:35:50:40 | reader | FreemarkerSSTI.java:44:17:44:44 | getParameter(...) : String | FreemarkerSSTI.java:50:35:50:40 | reader | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:44:17:44:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:61:35:61:44 | sourceCode | FreemarkerSSTI.java:56:23:56:56 | getParameter(...) : String | FreemarkerSSTI.java:61:35:61:44 | sourceCode | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:56:23:56:56 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:73:47:73:52 | reader | FreemarkerSSTI.java:67:17:67:44 | getParameter(...) : String | FreemarkerSSTI.java:73:47:73:52 | reader | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:67:17:67:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:87:47:87:52 | reader | FreemarkerSSTI.java:79:17:79:44 | getParameter(...) : String | FreemarkerSSTI.java:87:47:87:52 | reader | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:79:17:79:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:100:47:100:52 | reader | FreemarkerSSTI.java:93:17:93:44 | getParameter(...) : String | FreemarkerSSTI.java:100:47:100:52 | reader | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:93:17:93:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:109:42:109:45 | code | FreemarkerSSTI.java:105:17:105:44 | getParameter(...) : String | FreemarkerSSTI.java:109:42:109:45 | code | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:105:17:105:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:119:42:119:45 | code | FreemarkerSSTI.java:114:17:114:44 | getParameter(...) : String | FreemarkerSSTI.java:119:42:119:45 | code | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:114:17:114:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| FreemarkerSSTI.java:130:22:130:25 | root | FreemarkerSSTI.java:125:17:125:44 | getParameter(...) : String | FreemarkerSSTI.java:130:22:130:25 | root | Potential arbitrary code execution due to $@. | FreemarkerSSTI.java:125:17:125:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| JinJavaSSTI.java:25:44:25:51 | template | JinJavaSSTI.java:21:21:21:52 | getParameter(...) : String | JinJavaSSTI.java:25:44:25:51 | template | Potential arbitrary code execution due to $@. | JinJavaSSTI.java:21:21:21:52 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| JinJavaSSTI.java:34:55:34:62 | template | JinJavaSSTI.java:30:21:30:52 | getParameter(...) : String | JinJavaSSTI.java:34:55:34:62 | template | Potential arbitrary code execution due to $@. | JinJavaSSTI.java:30:21:30:52 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| JinJavaSSTI.java:46:55:46:62 | template | JinJavaSSTI.java:39:21:39:52 | getParameter(...) : String | JinJavaSSTI.java:46:55:46:62 | template | Potential arbitrary code execution due to $@. | JinJavaSSTI.java:39:21:39:52 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| PebbleSSTI.java:21:56:21:59 | code | PebbleSSTI.java:18:17:18:44 | getParameter(...) : String | PebbleSSTI.java:21:56:21:59 | code | Potential arbitrary code execution due to $@. | PebbleSSTI.java:18:17:18:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| PebbleSSTI.java:28:63:28:66 | code | PebbleSSTI.java:25:17:25:44 | getParameter(...) : String | PebbleSSTI.java:28:63:28:66 | code | Potential arbitrary code execution due to $@. | PebbleSSTI.java:25:17:25:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| ThymeleafSSTI.java:27:27:27:30 | code | ThymeleafSSTI.java:22:17:22:44 | getParameter(...) : String | ThymeleafSSTI.java:27:27:27:30 | code | Potential arbitrary code execution due to $@. | ThymeleafSSTI.java:22:17:22:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:38:45:38:48 | code | VelocitySSTI.java:31:17:31:44 | getParameter(...) : String | VelocitySSTI.java:38:45:38:48 | code | Potential arbitrary code execution due to $@. | VelocitySSTI.java:31:17:31:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:53:45:53:50 | reader | VelocitySSTI.java:44:17:44:44 | getParameter(...) : String | VelocitySSTI.java:53:45:53:50 | reader | Potential arbitrary code execution due to $@. | VelocitySSTI.java:44:17:44:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:63:25:63:30 | reader | VelocitySSTI.java:59:17:59:44 | getParameter(...) : String | VelocitySSTI.java:63:25:63:30 | reader | Potential arbitrary code execution due to $@. | VelocitySSTI.java:59:17:59:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:77:21:77:27 | context | VelocitySSTI.java:69:17:69:44 | getParameter(...) : String | VelocitySSTI.java:77:21:77:27 | context | Potential arbitrary code execution due to $@. | VelocitySSTI.java:69:17:69:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:89:60:89:66 | context | VelocitySSTI.java:83:17:83:44 | getParameter(...) : String | VelocitySSTI.java:89:60:89:66 | context | Potential arbitrary code execution due to $@. | VelocitySSTI.java:83:17:83:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:102:11:102:17 | context | VelocitySSTI.java:95:17:95:44 | getParameter(...) : String | VelocitySSTI.java:102:11:102:17 | context | Potential arbitrary code execution due to $@. | VelocitySSTI.java:95:17:95:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:115:11:115:17 | context | VelocitySSTI.java:108:17:108:44 | getParameter(...) : String | VelocitySSTI.java:115:11:115:17 | context | Potential arbitrary code execution due to $@. | VelocitySSTI.java:108:17:108:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
| VelocitySSTI.java:123:37:123:40 | code | VelocitySSTI.java:120:17:120:44 | getParameter(...) : String | VelocitySSTI.java:123:37:123:40 | code | Potential arbitrary code execution due to $@. | VelocitySSTI.java:120:17:120:44 | getParameter(...) | a template value loaded from a remote source. |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-094/TemplateInjection.ql
|
||||
@@ -0,0 +1,31 @@
|
||||
import javax.imageio.stream.FileImageInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.lang.String;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.thymeleaf.*;
|
||||
import org.thymeleaf.context.Context;
|
||||
|
||||
@Controller
|
||||
public class ThymeleafSSTI {
|
||||
String sourceName = "sourceName";
|
||||
|
||||
@GetMapping(value = "bad1")
|
||||
public void bad1(HttpServletRequest request) {
|
||||
String code = request.getParameter("code");
|
||||
Context ctx = new Context();
|
||||
try {
|
||||
FileWriter fw = new FileWriter(new File("as"));
|
||||
TemplateEngine templateEngine = new TemplateEngine();
|
||||
templateEngine.process(code, ctx, fw);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.lang.String;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.context.AbstractContext;
|
||||
import org.apache.velocity.context.Context;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.runtime.RuntimeServices;
|
||||
import org.apache.velocity.runtime.resource.util.StringResourceRepository;
|
||||
import org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl;
|
||||
|
||||
@Controller
|
||||
public class VelocitySSTI {
|
||||
String sourceName = "sourceName";
|
||||
|
||||
@GetMapping(value = "bad1")
|
||||
public void bad1(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = null;
|
||||
|
||||
String s = "We are using $project $name to render this.";
|
||||
StringWriter w = new StringWriter();
|
||||
// evaluate( Context context, Writer out, String logTag, String instring )
|
||||
Velocity.evaluate(context, w, "mystring", code);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad2")
|
||||
public void bad2(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = null;
|
||||
|
||||
String s = "We are using $project $name to render this.";
|
||||
StringWriter w = new StringWriter();
|
||||
StringReader reader = new StringReader(code);
|
||||
|
||||
// evaluate(Context context, Writer writer, String logTag, Reader reader)
|
||||
Velocity.evaluate(context, w, "mystring", reader);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad3")
|
||||
public void bad3(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
RuntimeServices runtimeServices = new RuntimeServices();
|
||||
StringReader reader = new StringReader(code);
|
||||
runtimeServices.parse(reader, new Template());
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad4")
|
||||
public void bad4(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = new VelocityContext();
|
||||
context.put("code", code);
|
||||
|
||||
StringWriter w = new StringWriter();
|
||||
StringReader reader = new StringReader("test");
|
||||
|
||||
Velocity.evaluate(context, w, "mystring", reader);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad5")
|
||||
public void bad5(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = new VelocityContext();
|
||||
context.put("code", code);
|
||||
|
||||
StringWriter w = new StringWriter();
|
||||
VelocityEngine.mergeTemplate("testtemplate.vm", "UTF-8", context, w);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad6")
|
||||
public void bad6(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = new VelocityContext();
|
||||
context.put("code", code);
|
||||
|
||||
StringWriter w = new StringWriter();
|
||||
Template t = new Template();
|
||||
t.merge(context, w);
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad7")
|
||||
public void bad7(HttpServletRequest request) {
|
||||
String name = "ttemplate";
|
||||
String code = request.getParameter("code");
|
||||
|
||||
VelocityContext context = new VelocityContext();
|
||||
context.put("code", code);
|
||||
|
||||
StringWriter w = new StringWriter();
|
||||
Template t = new Template();
|
||||
t.merge(context, w, new LinkedList<String>());
|
||||
}
|
||||
|
||||
@GetMapping(value = "bad8")
|
||||
public void bad8(HttpServletRequest request) {
|
||||
String code = request.getParameter("code");
|
||||
|
||||
StringResourceRepository repo = new StringResourceRepositoryImpl();
|
||||
repo.putStringResource("woogie2", code);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jython-2.7.2:${testdir}/../../../../experimental/stubs/rhino-1.7.13:${testdir}/../../../../stubs/bsh-2.0b5:${testdir}/../../../../experimental/stubs/jshell
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jython-2.7.2:${testdir}/../../../../experimental/stubs/rhino-1.7.13:${testdir}/../../../../stubs/bsh-2.0b5:${testdir}/../../../../experimental/stubs/jshell:${testdir}/../../../../experimental/stubs/apache-freemarker-2.3.31:${testdir}/../../../../experimental/stubs/jinjava-2.6.0:${testdir}/../../../../experimental/stubs/pebble-3.1.5:${testdir}/../../../../experimental/stubs/thymeleaf-3.0.14:${testdir}/../../../../experimental/stubs/apache-velocity-2.3
|
||||
7
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/cache/StringTemplateLoader.java
generated
vendored
Normal file
7
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/cache/StringTemplateLoader.java
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package freemarker.cache;
|
||||
|
||||
public class StringTemplateLoader {
|
||||
public StringTemplateLoader() {}
|
||||
public void putTemplate(java.lang.String name, java.lang.String templateContent){}
|
||||
public void putTemplate(java.lang.String name, java.lang.String templateContent, long lastModified){}
|
||||
}
|
||||
9
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/template/Configuration.java
generated
Normal file
9
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/template/Configuration.java
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
package freemarker.template;
|
||||
|
||||
import freemarker.template.Template;
|
||||
|
||||
public class Configuration implements ParserConfiguration {
|
||||
|
||||
public Configuration() {}
|
||||
public Template getTemplate(java.lang.String name){return null;}
|
||||
}
|
||||
3
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/template/ObjectWrapper.java
generated
Normal file
3
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/template/ObjectWrapper.java
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
package freemarker.template;
|
||||
|
||||
public interface ObjectWrapper {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package freemarker.template;
|
||||
|
||||
public interface ParserConfiguration {}
|
||||
55
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/template/Template.java
generated
Normal file
55
java/ql/test/experimental/stubs/apache-freemarker-2.3.31/freemarker/template/Template.java
generated
Normal file
@@ -0,0 +1,55 @@
|
||||
package freemarker.template;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.lang.String;
|
||||
|
||||
public class Template {
|
||||
|
||||
public Template(String name, Reader reader) {
|
||||
}
|
||||
|
||||
public Template(String name, Reader reader, Configuration cfg) {
|
||||
}
|
||||
|
||||
public Template(String name, Reader reader, Configuration cfg, String encoding) {
|
||||
}
|
||||
|
||||
public Template(String name, String sourceCode, Configuration cfg) {
|
||||
}
|
||||
|
||||
public Template(String name, String sourceName, Reader reader, Configuration cfg) {
|
||||
}
|
||||
|
||||
public Template(
|
||||
String name,
|
||||
String sourceName,
|
||||
Reader reader,
|
||||
Configuration cfg,
|
||||
ParserConfiguration customParserConfiguration,
|
||||
String encoding) {
|
||||
}
|
||||
|
||||
public Template(
|
||||
String name,
|
||||
String sourceName,
|
||||
Reader reader,
|
||||
Configuration cfg,
|
||||
String encoding) {
|
||||
}
|
||||
|
||||
public void process(java.lang.Object dataModel, java.io.Writer out) {
|
||||
}
|
||||
|
||||
public void process(
|
||||
java.lang.Object dataModel,
|
||||
java.io.Writer out,
|
||||
ObjectWrapper wrapper) {
|
||||
}
|
||||
|
||||
public void process(
|
||||
java.lang.Object dataModel,
|
||||
java.io.Writer out,
|
||||
ObjectWrapper wrapper,
|
||||
TemplateNodeModel rootNode) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package freemarker.template;
|
||||
|
||||
public interface TemplateNodeModel {}
|
||||
13
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/Template.java
generated
Normal file
13
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/Template.java
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.apache.velocity;
|
||||
|
||||
import org.apache.velocity.context.Context;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
public class Template {
|
||||
public void merge(Context context, Writer writer) {
|
||||
}
|
||||
|
||||
public void merge(Context context, Writer writer, List<String> macroLibraries) {
|
||||
}
|
||||
}
|
||||
10
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/VelocityContext.java
generated
Normal file
10
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/VelocityContext.java
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.apache.velocity;
|
||||
|
||||
import org.apache.velocity.context.AbstractContext;
|
||||
import org.apache.velocity.context.Context;
|
||||
import java.io.Writer;
|
||||
|
||||
public class VelocityContext extends AbstractContext implements Context {
|
||||
public VelocityContext() {
|
||||
}
|
||||
}
|
||||
20
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/VelocityEngine.java
generated
Normal file
20
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/VelocityEngine.java
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.apache.velocity;
|
||||
|
||||
import org.apache.velocity.context;
|
||||
import java.io.Writer;
|
||||
import java.lang.String;
|
||||
import java.io.Reader;
|
||||
|
||||
public class VelocityEngine {
|
||||
public static boolean evaluate(Context context, Writer out, String logTag, String instring) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean evaluate(Context context, Writer writer, String logTag, Reader reader) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean mergeTemplate(String templateName, String encoding, Context context, Writer writer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
15
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/app/Velocity.java
generated
Normal file
15
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/app/Velocity.java
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.apache.velocity.app;
|
||||
|
||||
import org.apache.velocity.context.Context;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
public class Velocity {
|
||||
public static boolean evaluate(Context context, Writer out, String logTag, String instring) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean evaluate(Context context, Writer writer, String logTag, Reader reader) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
20
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/app/VelocityEngine.java
generated
Normal file
20
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/app/VelocityEngine.java
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.apache.velocity.app;
|
||||
|
||||
import org.apache.velocity.context.Context;
|
||||
import java.io.Writer;
|
||||
import java.lang.String;
|
||||
import java.io.Reader;
|
||||
|
||||
public class VelocityEngine {
|
||||
public static boolean evaluate(Context context, Writer out, String logTag, String instring) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean evaluate(Context context, Writer writer, String logTag, Reader reader) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean mergeTemplate(String templateName, String encoding, Context context, Writer writer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
14
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/context/AbstractContext.java
generated
Normal file
14
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/context/AbstractContext.java
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
package org.apache.velocity.context;
|
||||
|
||||
import org.apache.velocity.context.Context;
|
||||
import java.io.Writer;
|
||||
|
||||
public class AbstractContext implements Context {
|
||||
public Object put(String key, Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object internalPut(String key, Object value) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
7
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/context/Context.java
generated
Normal file
7
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/context/Context.java
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.apache.velocity.context;
|
||||
|
||||
public interface Context {
|
||||
public Object put(String key, Object value);
|
||||
|
||||
public Object internalPut(String key, Object value);
|
||||
}
|
||||
25
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/runtime/RuntimeServices.java
generated
Normal file
25
java/ql/test/experimental/stubs/apache-velocity-2.3/org/apache/velocity/runtime/RuntimeServices.java
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
package org.apache.velocity.runtime;
|
||||
|
||||
import org.apache.velocity.runtime.parser.node.*;
|
||||
|
||||
import org.apache.velocity.context.Context;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import org.apache.velocity.Template;
|
||||
|
||||
public class RuntimeServices {
|
||||
public RuntimeServices() {
|
||||
}
|
||||
|
||||
public static SimpleNode parse(Reader reader, Template template) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean evaluate(Context context, Writer out, String logTag, String instring) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean evaluate(Context context, Writer writer, String logTag, Reader reader) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.apache.velocity.runtime;
|
||||
|
||||
import org.apache.velocity.runtime.parser.node.*;
|
||||
|
||||
public class RuntimeSingleton {
|
||||
public static SimpleNode parse(Reader reader, Template template) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.apache.velocity.runtime.parser.node;
|
||||
|
||||
public class SimpleNode {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.apache.velocity.runtime.resource.util;
|
||||
|
||||
public interface StringResourceRepository {
|
||||
public void putStringResource(String name, String body);
|
||||
|
||||
public void putStringResource(String name, String body, String encoding);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.apache.velocity.runtime.resource.util;
|
||||
|
||||
public class StringResourceRepositoryImpl implements StringResourceRepository {
|
||||
public void putStringResource(String name, String body) {
|
||||
}
|
||||
|
||||
public void putStringResource(String name, String body, String encoding) {
|
||||
}
|
||||
}
|
||||
24
java/ql/test/experimental/stubs/jinjava-2.6.0/com/hubspot/jinjava/Jinjava.java
generated
Normal file
24
java/ql/test/experimental/stubs/jinjava-2.6.0/com/hubspot/jinjava/Jinjava.java
generated
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.hubspot.jinjava;
|
||||
|
||||
import com.hubspot.jinjava.JinjavaConfig;
|
||||
import com.hubspot.jinjava.interpret.RenderResult;
|
||||
|
||||
import java.lang.String;
|
||||
import java.util.Map;
|
||||
|
||||
public class Jinjava {
|
||||
public Jinjava() {
|
||||
}
|
||||
|
||||
public String render(String template, Map<String, ?> bindings) {
|
||||
return "test";
|
||||
};
|
||||
|
||||
public RenderResult renderForResult(String template, Map<String, ?> bindings) {
|
||||
return new RenderResult("result");
|
||||
}
|
||||
|
||||
public RenderResult renderForResult(String template, Map<String, ?> bindings, JinjavaConfig renderConfig) {
|
||||
return new RenderResult("result");
|
||||
}
|
||||
}
|
||||
5
java/ql/test/experimental/stubs/jinjava-2.6.0/com/hubspot/jinjava/JinjavaConfig.java
generated
Normal file
5
java/ql/test/experimental/stubs/jinjava-2.6.0/com/hubspot/jinjava/JinjavaConfig.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.hubspot.jinjava;
|
||||
|
||||
public class JinjavaConfig {
|
||||
|
||||
}
|
||||
6
java/ql/test/experimental/stubs/jinjava-2.6.0/com/hubspot/jinjava/interpret/RenderResult.java
generated
Normal file
6
java/ql/test/experimental/stubs/jinjava-2.6.0/com/hubspot/jinjava/interpret/RenderResult.java
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
package com.hubspot.jinjava.interpret;
|
||||
|
||||
public class RenderResult {
|
||||
public RenderResult(String result) {
|
||||
}
|
||||
}
|
||||
27
java/ql/test/experimental/stubs/pebble-3.1.5/com/mitchellbosecke/pebble/PebbleEngine.java
generated
Normal file
27
java/ql/test/experimental/stubs/pebble-3.1.5/com/mitchellbosecke/pebble/PebbleEngine.java
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.mitchellbosecke.pebble;
|
||||
|
||||
import com.mitchellbosecke.pebble.template.*;
|
||||
|
||||
public class PebbleEngine {
|
||||
public static class Builder {
|
||||
public Builder() {
|
||||
};
|
||||
|
||||
public PebbleEngine build() {
|
||||
return new PebbleEngine();
|
||||
}
|
||||
};
|
||||
|
||||
PebbleEngine() {
|
||||
}
|
||||
|
||||
public PebbleTemplate getLiteralTemplate(String templateName) {
|
||||
return new PebbleTemplate() {
|
||||
};
|
||||
}
|
||||
|
||||
public PebbleTemplate getTemplate(String templateName) {
|
||||
return new PebbleTemplate() {
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.mitchellbosecke.pebble.template;
|
||||
|
||||
public interface PebbleTemplate {}
|
||||
28
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/ITemplateEngine.java
generated
Normal file
28
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/ITemplateEngine.java
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.thymeleaf;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.lang.String;
|
||||
import java.util.Set;
|
||||
import org.thymeleaf.context.IContext;
|
||||
import org.thymeleaf.*;
|
||||
|
||||
public interface ITemplateEngine {
|
||||
|
||||
public String process(String template, Set<String> templateSelectors, IContext context);
|
||||
|
||||
public void process(String template, Set<String> templateSelectors, IContext context, Writer writer);
|
||||
|
||||
public String process(String template, IContext context);
|
||||
|
||||
public void process(String template, IContext context, Writer writer);
|
||||
|
||||
public String process(TemplateSpec templateSpec, IContext context);
|
||||
|
||||
public void process(TemplateSpec templateSpec, IContext context, Writer writer);
|
||||
|
||||
public IThrottledTemplateProcessor processThrottled(String template, Set<String> templateSelectors, IContext context);
|
||||
|
||||
public IThrottledTemplateProcessor processThrottled(String template, IContext context);
|
||||
|
||||
public IThrottledTemplateProcessor processThrottled(TemplateSpec templateSpec, IContext context);
|
||||
}
|
||||
5
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/IThrottledTemplateProcessor.java
generated
Normal file
5
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/IThrottledTemplateProcessor.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package org.thymeleaf;
|
||||
|
||||
public interface IThrottledTemplateProcessor {
|
||||
|
||||
}
|
||||
51
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/TemplateEngine.java
generated
Normal file
51
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/TemplateEngine.java
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
package org.thymeleaf;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.lang.String;
|
||||
import java.util.Set;
|
||||
import org.thymeleaf.context.IContext;
|
||||
import org.thymeleaf.TemplateSpec;
|
||||
import org.thymeleaf.ITemplateEngine;
|
||||
import org.thymeleaf.IThrottledTemplateProcessor;
|
||||
|
||||
public class TemplateEngine implements ITemplateEngine {
|
||||
|
||||
public String process(String template, Set<String> templateSelectors, IContext context) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void process(String template, Set<String> templateSelectors, IContext context, Writer writer) {
|
||||
}
|
||||
|
||||
public String process(String template, IContext context) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void process(String template, IContext context, Writer writer) {
|
||||
}
|
||||
|
||||
public String process(TemplateSpec templateSpec, IContext context) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void process(TemplateSpec templateSpec, IContext context, Writer writer) {
|
||||
}
|
||||
|
||||
public IThrottledTemplateProcessor processThrottled(String template, Set<String> templateSelectors,
|
||||
IContext context) {
|
||||
return new IThrottledTemplateProcessor() {
|
||||
};
|
||||
}
|
||||
|
||||
public IThrottledTemplateProcessor processThrottled(String template, IContext context) {
|
||||
return new IThrottledTemplateProcessor() {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public IThrottledTemplateProcessor processThrottled(TemplateSpec templateSpec, IContext context) {
|
||||
return new IThrottledTemplateProcessor() {
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
5
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/TemplateSpec.java
generated
Normal file
5
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/TemplateSpec.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package org.thymeleaf;
|
||||
|
||||
public class TemplateSpec {
|
||||
|
||||
}
|
||||
7
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/context/Context.java
generated
Normal file
7
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/context/Context.java
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.thymeleaf.context;
|
||||
|
||||
import org.thymeleaf.context.IContext;
|
||||
|
||||
public class Context implements IContext {
|
||||
|
||||
}
|
||||
5
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/context/IContext.java
generated
Normal file
5
java/ql/test/experimental/stubs/thymeleaf-3.0.14/org/thymeleaf/context/IContext.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package org.thymeleaf.context;
|
||||
|
||||
public interface IContext {
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import semmle.javascript.security.dataflow.StoredXssQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* An instance of `mysql.createConnection()`, tracked globally.
|
||||
* Gets an instance of `mysql.createConnection()`, tracked globally.
|
||||
*/
|
||||
DataFlow::SourceNode mysqlConnection(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
@@ -23,7 +23,7 @@ DataFlow::SourceNode mysqlConnection(DataFlow::TypeTracker t) {
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of `mysql.createConnection()`, tracked globally.
|
||||
* Gets an instance of `mysql.createConnection()`, tracked globally.
|
||||
*/
|
||||
DataFlow::SourceNode mysqlConnection() { result = mysqlConnection(DataFlow::TypeTracker::end()) }
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ int getNumCharsInFunction(Function f) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of characters a feature can be.
|
||||
* Gets the maximum number of characters a feature can be.
|
||||
* The evaluator string limit is 5395415 characters. We choose a limit lower than this.
|
||||
*/
|
||||
private int getMaxChars() { result = 1000000 }
|
||||
|
||||
@@ -12,7 +12,7 @@ import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures
|
||||
import experimental.adaptivethreatmodeling.EndpointTypes
|
||||
import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
|
||||
|
||||
/** The positive endpoint type for which you wish to find misclassified examples. */
|
||||
/** Gets the positive endpoint type for which you wish to find misclassified examples. */
|
||||
EndpointType getEndpointType() { result instanceof NosqlInjectionSinkType }
|
||||
|
||||
/** Get a positive endpoint. This will be run through the classifier to determine whether it is misclassified. */
|
||||
|
||||
@@ -1,50 +1,62 @@
|
||||
# NoSQL database query built from user-controlled sources (experimental)
|
||||
If a database query (such as a SQL or NoSQL query) is built from user-provided data without sufficient sanitization, a malicious user may be able to run malicious database queries.
|
||||
If a database query is built from user-provided data without sufficient sanitization, a user may be able to run malicious database queries.
|
||||
|
||||
Note: This CodeQL query is an experimental query. Experimental queries generate alerts using machine learning. They might include more false positives but they will improve over time.
|
||||
|
||||
|
||||
## Recommendation
|
||||
Most database connector libraries offer a way of safely embedding untrusted data into a query by means of query parameters or prepared statements.
|
||||
|
||||
For NoSQL queries, make use of an operator like MongoDB's `$eq` to ensure that untrusted data is interpreted as a literal value and not as a query object.
|
||||
|
||||
Ensure that untrusted data is interpreted as a literal value and not as a query object, eg., by using an operator like MongoDB's `$eq`.
|
||||
|
||||
## Example
|
||||
In the following example, assume the function `handler` is an HTTP request handler in a web application, whose parameter `req` contains the request object.
|
||||
In the following example, an `express.js` application is defining two endpoints that permit a user to query a MongoDB database.
|
||||
|
||||
The handler constructs two copies of the same SQL query involving user input taken from the request object, once unsafely using string concatenation, and once safely using query parameters.
|
||||
In each case, the handler constructs two copies of the same query involving user input taken from the request object. In both handlers, the input is parsed using the `body-parser` library, which will transform the request data that arrives as a string to JSON objects.
|
||||
|
||||
In the first case, the query string `query1` is built by directly concatenating a user-supplied request parameter with some string literals. The parameter may include quote characters, so this code is vulnerable to a SQL injection attack.
|
||||
In the first case, `/search1`, the input is used as a query object. This means that a malicious user is able to inject queries that select more data than the developer intended.
|
||||
|
||||
In the second case, the parameter is embedded into the query string `query2` using query parameters. In this example, we use the API offered by the `pg` Postgres database connector library, but other libraries offer similar features. This version is immune to injection attacks.
|
||||
In the second case, `/search2`, parts of the input are converted to a string representation and then used with the `$eq` operator to construct a query object.
|
||||
|
||||
|
||||
```javascript
|
||||
const app = require("express")(),
|
||||
pg = require("pg"),
|
||||
pool = new pg.Pool(config);
|
||||
mongodb = require("mongodb"),
|
||||
bodyParser = require('body-parser');
|
||||
|
||||
app.get("search", function handler(req, res) {
|
||||
// BAD: the category might have SQL special characters in it
|
||||
var query1 =
|
||||
"SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" +
|
||||
req.params.category +
|
||||
"' ORDER BY PRICE";
|
||||
pool.query(query1, [], function(err, results) {
|
||||
// process results
|
||||
});
|
||||
const client = new MongoClient('mongodb://localhost:27017/test');
|
||||
|
||||
// GOOD: use parameters
|
||||
var query2 =
|
||||
"SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=$1" + " ORDER BY PRICE";
|
||||
pool.query(query2, [req.params.category], function(err, results) {
|
||||
// process results
|
||||
});
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
app.get("/search1", async function handler(req, res) {
|
||||
await client.connect();
|
||||
const db = client.db('test');
|
||||
const doc = db.collection('doc');
|
||||
|
||||
const result = doc.find({
|
||||
// BAD:
|
||||
// This is vulnerable.
|
||||
// Eg., req.body.title might be the object { $ne: "foobarbaz" }, and the
|
||||
// endpoint would return all data.
|
||||
title: req.body.title
|
||||
});
|
||||
|
||||
res.send(await result);
|
||||
});
|
||||
|
||||
app.get("/search2", async function handler(req, res) {
|
||||
await client.connect();
|
||||
const db = client.db('test');
|
||||
const doc = db.collection('doc');
|
||||
|
||||
// GOOD:
|
||||
// The input is converted to a string, and matched using the $eq operator.
|
||||
// At most one datum is returned.
|
||||
const result = await doc.find({ title: { $eq: `${req.body.title}` } });
|
||||
|
||||
res.send(await result);
|
||||
});
|
||||
```
|
||||
|
||||
## References
|
||||
* Wikipedia: [SQL injection](https://en.wikipedia.org/wiki/SQL_injection).
|
||||
* Acunetix Blog: [NoSQL Injections and How to Avoid Them](https://www.acunetix.com/blog/web-security-zone/nosql-injections/).
|
||||
* MongoDB: [$eq operator](https://docs.mongodb.com/manual/reference/operator/query/eq).
|
||||
* MongoDB: [$ne operator](https://docs.mongodb.com/manual/reference/operator/query/ne).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SQL database query built from user-controlled sources (experimental)
|
||||
If a database query (such as a SQL or NoSQL query) is built from user-provided data without sufficient sanitization, a malicious user may be able to run malicious database queries.
|
||||
If a SQL query is built from user-provided data without sufficient sanitization, a malicious user may be able to run malicious database queries.
|
||||
|
||||
Note: This CodeQL query is an experimental query. Experimental queries generate alerts using machine learning. They might include more false positives but they will improve over time.
|
||||
|
||||
@@ -7,11 +7,8 @@ Note: This CodeQL query is an experimental query. Experimental queries generate
|
||||
## Recommendation
|
||||
Most database connector libraries offer a way of safely embedding untrusted data into a query by means of query parameters or prepared statements.
|
||||
|
||||
For NoSQL queries, make use of an operator like MongoDB's `$eq` to ensure that untrusted data is interpreted as a literal value and not as a query object.
|
||||
|
||||
|
||||
## Example
|
||||
In the following example, assume the function `handler` is an HTTP request handler in a web application, whose parameter `req` contains the request object.
|
||||
In the following example, an `express.js` application is defining two endpoints that permit a user to query a postgres database.
|
||||
|
||||
The handler constructs two copies of the same SQL query involving user input taken from the request object, once unsafely using string concatenation, and once safely using query parameters.
|
||||
|
||||
@@ -47,4 +44,3 @@ app.get("search", function handler(req, res) {
|
||||
|
||||
## References
|
||||
* Wikipedia: [SQL injection](https://en.wikipedia.org/wiki/SQL_injection).
|
||||
* MongoDB: [$eq operator](https://docs.mongodb.com/manual/reference/operator/query/eq).
|
||||
|
||||
@@ -16,7 +16,7 @@ module ArrayTaintTracking {
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint propagating data flow edge from `pred` to `succ` caused by a call `call` to a builtin array functions.
|
||||
* Holds if there is a taint propagating data flow edge from `pred` to `succ` caused by a call `call` to a builtin array functions.
|
||||
*/
|
||||
predicate arrayFunctionTaintStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode call) {
|
||||
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
|
||||
@@ -357,7 +357,7 @@ private module ArrayLibraries {
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a library that copies the elements of an array into another array.
|
||||
* Gets a call to a library that copies the elements of an array into another array.
|
||||
* E.g. `array-union` that creates a union of multiple arrays, or `array-uniq` that creates an array with unique elements.
|
||||
*/
|
||||
DataFlow::CallNode arrayCopyCall(DataFlow::Node array) {
|
||||
|
||||
@@ -300,7 +300,7 @@ module DOM {
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that might refer to some form.
|
||||
* Gets a data flow node that might refer to some form.
|
||||
* Either by a read like `document.forms[0]`, or a property read from `document` with some constant property-name.
|
||||
* E.g. if `<form name="foobar">..</form>` exists, then `document.foobar` refers to that form.
|
||||
*/
|
||||
|
||||
@@ -182,6 +182,8 @@ private class CloneStep extends PreCallGraphStep {
|
||||
call = DataFlow::moduleImport(["clone", "fclone", "sort-keys", "camelcase-keys"]).getACall()
|
||||
or
|
||||
call = DataFlow::moduleMember("json-cycle", ["decycle", "retrocycle"]).getACall()
|
||||
or
|
||||
call = LodashUnderscore::member(["clone", "cloneDeep"]).getACall()
|
||||
|
|
||||
pred = call.getArgument(0) and
|
||||
succ = call
|
||||
|
||||
@@ -173,6 +173,24 @@ module HTML {
|
||||
DocumentElement() { getName() = "html" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An HTML `<iframe>` element.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* <iframe src="https://test.local/somepage.html"></iframe>
|
||||
* ```
|
||||
*/
|
||||
class IframeElement extends Element {
|
||||
IframeElement() { getName() = "iframe" }
|
||||
|
||||
/**
|
||||
* Gets the value of the `src` attribute.
|
||||
*/
|
||||
string getSourcePath() { result = getAttributeByName("src").getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An HTML `<script>` element.
|
||||
*
|
||||
@@ -207,6 +225,11 @@ module HTML {
|
||||
*/
|
||||
string getSourcePath() { result = getAttributeByName("src").getValue() }
|
||||
|
||||
/**
|
||||
* Gets the value of the `integrity` attribute.
|
||||
*/
|
||||
string getIntegrityDigest() { result = getAttributeByName("integrity").getValue() }
|
||||
|
||||
/**
|
||||
* Gets the folder relative to which the `src` attribute is resolved.
|
||||
*/
|
||||
|
||||
@@ -56,7 +56,7 @@ module JsonSchema {
|
||||
|
||||
/** Provides a model of the `ajv` library. */
|
||||
module Ajv {
|
||||
/** A method on `Ajv` that returns `this`. */
|
||||
/** Gets a method on `Ajv` that returns `this`. */
|
||||
private string chainedMethod() {
|
||||
result =
|
||||
["addSchema", "addMetaSchema", "removeSchema", "addFormat", "addKeyword", "removeKeyword"]
|
||||
@@ -141,7 +141,7 @@ module JsonSchema {
|
||||
|
||||
/** Provides a model for working with the [`joi`](https://npmjs.org/package/joi) library. */
|
||||
module Joi {
|
||||
/** A schema created using `joi.object()` or other schemas that might refer an object schema. */
|
||||
/** Gets a schema created using `joi.object()` or other schemas that might refer an object schema. */
|
||||
private API::Node objectSchema() {
|
||||
// A call that creates a schema that might be an object schema.
|
||||
result =
|
||||
|
||||
@@ -87,6 +87,15 @@ private DataFlow::Node getAValueExportedByPackage() {
|
||||
result = getAnExportFromModule(mod)
|
||||
)
|
||||
or
|
||||
// require("./other-module.js"); inside an AMD module.
|
||||
exists(Module mod, CallExpr call |
|
||||
call = getAValueExportedByPackage().asExpr() and
|
||||
call = any(AmdModuleDefinition e).getARequireCall() and
|
||||
mod = call.getAnArgument().(Import).getImportedModule()
|
||||
|
|
||||
result = getAnExportFromModule(mod)
|
||||
)
|
||||
or
|
||||
// module.exports = class Foo {
|
||||
// bar() {} // <- result
|
||||
// static baz() {} // <- result
|
||||
|
||||
@@ -503,7 +503,7 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
|
||||
/** This SSA definition corresponds to the definition of `v` at `def`. */
|
||||
predicate defines(VarDef d, SsaSourceVariable v) { this = TExplicitDef(_, _, d, v) }
|
||||
|
||||
/** The variable definition wrapped by this SSA definition. */
|
||||
/** Gets the variable definition wrapped by this SSA definition. */
|
||||
VarDef getDef() { this = TExplicitDef(_, _, result, _) }
|
||||
|
||||
/** Gets the basic block to which this definition belongs. */
|
||||
|
||||
@@ -651,10 +651,18 @@ module DataFlow {
|
||||
override string getPropertyName() { result = astNode.getArgument(1).getStringValue() }
|
||||
|
||||
override Node getRhs() {
|
||||
exists(ObjectExpr obj | obj = astNode.getArgument(2) |
|
||||
result = obj.getPropertyByName("value").getInit().flow()
|
||||
exists(DataFlow::SourceNode descriptor |
|
||||
descriptor = astNode.getArgument(2).flow().getALocalSource()
|
||||
|
|
||||
result =
|
||||
descriptor
|
||||
.getAPropertyWrite("get")
|
||||
.getRhs()
|
||||
.getALocalSource()
|
||||
.(DataFlow::FunctionNode)
|
||||
.getAReturn()
|
||||
or
|
||||
result = obj.getPropertyByName("get").getInit().flow().(DataFlow::FunctionNode).getAReturn()
|
||||
result = descriptor.getAPropertyWrite("value").getRhs()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -787,16 +787,16 @@ class MemberKind extends string {
|
||||
}
|
||||
|
||||
module MemberKind {
|
||||
/** The kind of a method, such as `m() {}` */
|
||||
/** Gets the kind of a method, such as `m() {}` */
|
||||
MemberKind method() { result = "method" }
|
||||
|
||||
/** The kind of a getter accessor, such as `get f() {}`. */
|
||||
/** Gets the kind of a getter accessor, such as `get f() {}`. */
|
||||
MemberKind getter() { result = "getter" }
|
||||
|
||||
/** The kind of a setter accessor, such as `set f() {}`. */
|
||||
/** Gets the kind of a setter accessor, such as `set f() {}`. */
|
||||
MemberKind setter() { result = "setter" }
|
||||
|
||||
/** The `getter` and `setter` kinds. */
|
||||
/** Gets the `getter` and `setter` kinds. */
|
||||
MemberKind accessor() { result = getter() or result = setter() }
|
||||
|
||||
/**
|
||||
|
||||
@@ -804,13 +804,13 @@ module TaintTracking {
|
||||
}
|
||||
|
||||
/**
|
||||
* A pseudo-property a `URL` that stores a value that can be obtained
|
||||
* Gets a pseudo-property a `URL` that stores a value that can be obtained
|
||||
* with a `get` or `getAll` call to the `searchParams` property.
|
||||
*/
|
||||
private string hiddenUrlPseudoProperty() { result = "$hiddenSearchPararms" }
|
||||
|
||||
/**
|
||||
* A pseudo-property on a `URLSearchParams` that can be obtained
|
||||
* Gets a pseudo-property on a `URLSearchParams` that can be obtained
|
||||
* with a `get` or `getAll` call.
|
||||
*/
|
||||
private string getableUrlPseudoProperty() { result = "$gettableSearchPararms" }
|
||||
|
||||
@@ -480,7 +480,7 @@ private module CachedSteps {
|
||||
}
|
||||
|
||||
/**
|
||||
* A step from `pred` to `succ` through a call to an identity function.
|
||||
* Holds if there is a step from `pred` to `succ` through a call to an identity function.
|
||||
*/
|
||||
cached
|
||||
predicate identityFunctionStep(DataFlow::Node pred, DataFlow::CallNode succ) {
|
||||
|
||||
@@ -21,7 +21,7 @@ abstract class Dependency extends Locatable {
|
||||
abstract predicate info(string id, string v);
|
||||
|
||||
/**
|
||||
* A use of this dependency, which is of the given `kind`.
|
||||
* Gets a use of this dependency, which is of the given `kind`.
|
||||
*
|
||||
* Currently, the only supported kinds are `"import"` and `"use"`.
|
||||
*/
|
||||
|
||||
@@ -99,7 +99,7 @@ private predicate isBrowserifyDependencyMap(ObjectExpr deps) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that looks like a bundled module created
|
||||
* Holds if `m` is a function that looks like a bundled module created
|
||||
* by Webpack.
|
||||
*
|
||||
* Parameters must be named either `module` or `exports`,
|
||||
|
||||
@@ -6,14 +6,14 @@ import javascript
|
||||
private import semmle.javascript.security.dataflow.Xss as Xss
|
||||
|
||||
module Cheerio {
|
||||
/** A reference to the `cheerio` function, possibly with a loaded DOM. */
|
||||
/** Gets a reference to the `cheerio` function, possibly with a loaded DOM. */
|
||||
private API::Node cheerioApi() {
|
||||
result = API::moduleImport("cheerio")
|
||||
or
|
||||
result = cheerioApi().getMember(["load", "parseHTML"]).getReturn()
|
||||
}
|
||||
|
||||
/** A reference to the `cheerio` function, possibly with a loaded DOM. */
|
||||
/** Gets a reference to the `cheerio` function, possibly with a loaded DOM. */
|
||||
DataFlow::SourceNode cheerioRef() { result = cheerioApi().getAUse() }
|
||||
|
||||
/**
|
||||
|
||||
@@ -807,7 +807,7 @@ module ClientRequest {
|
||||
*/
|
||||
private module ApolloClient {
|
||||
/**
|
||||
* A function from `apollo-client` that accepts an options object that may contain a `uri` property.
|
||||
* Gets a function from `apollo-client` that accepts an options object that may contain a `uri` property.
|
||||
*/
|
||||
API::Node apolloUriCallee() {
|
||||
result = API::moduleImport("apollo-link-http").getMember(["HttpLink", "createHttpLink"])
|
||||
|
||||
@@ -51,12 +51,12 @@ module CookieWrites {
|
||||
}
|
||||
|
||||
/**
|
||||
* The flag that indicates that a cookie is secure.
|
||||
* Gets the flag that indicates that a cookie is secure.
|
||||
*/
|
||||
string secure() { result = "secure" }
|
||||
|
||||
/**
|
||||
* The flag that indicates that a cookie is HttpOnly.
|
||||
* Gets the flag that indicates that a cookie is HttpOnly.
|
||||
*/
|
||||
string httpOnly() { result = "httpOnly" }
|
||||
}
|
||||
|
||||
@@ -261,4 +261,15 @@ module Hapi {
|
||||
|
||||
override DataFlow::Node getTemplateParamsNode() { result = getArgument(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A return from a route handler.
|
||||
*/
|
||||
private class HandlerReturn extends HTTP::ResponseSendArgument {
|
||||
RouteHandler handler;
|
||||
|
||||
HandlerReturn() { this = handler.(DataFlow::FunctionNode).getAReturn().asExpr() }
|
||||
|
||||
override RouteHandler getRouteHandler() { result = handler }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ private module Immutable {
|
||||
}
|
||||
|
||||
/**
|
||||
* An import of the `Immutable` library.
|
||||
* Gets an import of the `Immutable` library.
|
||||
*/
|
||||
API::Node immutableImport() {
|
||||
result = API::moduleImport("immutable")
|
||||
@@ -31,7 +31,7 @@ private module Immutable {
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of any immutable collection.
|
||||
* Gets an instance of any immutable collection.
|
||||
*
|
||||
* This predicate keeps track of which values in the program are Immutable collections.
|
||||
*/
|
||||
|
||||
@@ -36,10 +36,10 @@ module LdapJS {
|
||||
|
||||
/** A creation of an LDAPjs filter, or object containing a filter, that doesn't sanitizes the input. */
|
||||
abstract class TaintPreservingLdapFilterStep extends DataFlow::Node {
|
||||
/** The input that creates (part of) an LDAPjs filter. */
|
||||
/** Gets the input that creates (part of) an LDAPjs filter. */
|
||||
abstract DataFlow::Node getInput();
|
||||
|
||||
/** The resulting LDAPjs filter. */
|
||||
/** Gets the resulting LDAPjs filter. */
|
||||
abstract DataFlow::Node getOutput();
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ module Markdown {
|
||||
*/
|
||||
private module Unified {
|
||||
/**
|
||||
* The creation of a parser from `unified`.
|
||||
* Gets a parser from `unified`.
|
||||
* The `remark` module is a shorthand that initializes `unified` with a markdown parser.
|
||||
*/
|
||||
DataFlow::CallNode unified() {
|
||||
@@ -152,7 +152,7 @@ module Markdown {
|
||||
*/
|
||||
private module MarkdownIt {
|
||||
/**
|
||||
* The creation of a parser from `markdown-it`.
|
||||
* Gets a creation of a parser from `markdown-it`.
|
||||
*/
|
||||
private API::Node markdownIt() {
|
||||
exists(API::InvokeNode call |
|
||||
|
||||
@@ -8,7 +8,7 @@ private module Micro {
|
||||
private import DataFlow
|
||||
|
||||
/**
|
||||
* A node that should be interpreted as a route handler, to use as starting
|
||||
* Gets a node that should be interpreted as a route handler, to use as starting
|
||||
* point for back-tracking.
|
||||
*/
|
||||
Node microRouteHandlerSink() {
|
||||
|
||||
@@ -493,7 +493,7 @@ module NodeJSLib {
|
||||
*/
|
||||
module FS {
|
||||
/**
|
||||
* A member `member` from module `fs` or its drop-in replacements `graceful-fs`, `fs-extra`, `original-fs`.
|
||||
* Gets a member `member` from module `fs` or its drop-in replacements `graceful-fs`, `fs-extra`, `original-fs`.
|
||||
*/
|
||||
DataFlow::SourceNode moduleMember(string member) {
|
||||
result = fsModule(DataFlow::TypeTracker::end()).getAPropertyRead(member)
|
||||
|
||||
@@ -9,12 +9,12 @@ import javascript
|
||||
*/
|
||||
module Puppeteer {
|
||||
/**
|
||||
* A reference to a module import of puppeteer.
|
||||
* Gets a reference to a module import of puppeteer.
|
||||
*/
|
||||
private API::Node puppeteer() { result = API::moduleImport(["puppeteer", "puppeteer-core"]) }
|
||||
|
||||
/**
|
||||
* A reference to a `Browser` from puppeteer.
|
||||
* Gets a reference to a `Browser` from puppeteer.
|
||||
*/
|
||||
private API::Node browser() {
|
||||
result = API::Node::ofType("puppeteer", "Browser")
|
||||
@@ -25,7 +25,7 @@ module Puppeteer {
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to a `Page` from puppeteer.
|
||||
* Gets a reference to a `Page` from puppeteer.
|
||||
*/
|
||||
API::Node page() {
|
||||
result = API::Node::ofType("puppeteer", "Page")
|
||||
@@ -38,7 +38,7 @@ module Puppeteer {
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to a `Target` from puppeteer.
|
||||
* Gets a reference to a `Target` from puppeteer.
|
||||
*/
|
||||
private API::Node target() {
|
||||
result = API::Node::ofType("puppeteer", "Target")
|
||||
@@ -51,7 +51,7 @@ module Puppeteer {
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to a `BrowserContext` from puppeteer.
|
||||
* Gets a reference to a `BrowserContext` from puppeteer.
|
||||
*/
|
||||
private API::Node context() {
|
||||
result = API::Node::ofType("puppeteer", "BrowserContext")
|
||||
|
||||
@@ -27,7 +27,7 @@ module Redux {
|
||||
importer.getADependenciesObject("").getADependency(dependency.getPackageName(), _)
|
||||
}
|
||||
|
||||
/** A package that can be considered an entry point for a Redux app. */
|
||||
/** Gets a package that can be considered an entry point for a Redux app. */
|
||||
private PackageJSON entryPointPackage() {
|
||||
result = getPackageJson(any(StoreCreation c).getFile())
|
||||
or
|
||||
|
||||
@@ -376,7 +376,7 @@ private module Sqlite {
|
||||
result = API::Node::ofType("sqlite3", "Database")
|
||||
}
|
||||
|
||||
/** A call to a query method on a Sqlite database instance that returns the same instance. */
|
||||
/** Gets a call to a query method on a Sqlite database instance that returns the same instance. */
|
||||
private API::Node getAChainingQueryCall() {
|
||||
result = database().getMember(["all", "each", "exec", "get", "run"]).getReturn()
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ module Vue {
|
||||
*/
|
||||
DataFlow::SourceNode vue() { result = vueLibrary().getAnImmediateUse() }
|
||||
|
||||
/** An API node referring to a component or `Vue`. */
|
||||
/** Gets an API node referring to a component or `Vue`. */
|
||||
private API::Node component() {
|
||||
result = vueLibrary()
|
||||
or
|
||||
@@ -683,7 +683,7 @@ module Vue {
|
||||
}
|
||||
}
|
||||
|
||||
/** An API node referring to a `RouteConfig` being passed to `vue-router`. */
|
||||
/** Gets an API node referring to a `RouteConfig` being passed to `vue-router`. */
|
||||
private API::Node routeConfig() {
|
||||
result = API::moduleImport("vue-router").getParameter(0).getMember("routes").getAMember()
|
||||
or
|
||||
|
||||
@@ -376,7 +376,7 @@ module Vuex {
|
||||
importer.getADependenciesObject("").getADependency(dependency.getPackageName(), _)
|
||||
}
|
||||
|
||||
/** A package that can be considered an entry point for a Vuex app. */
|
||||
/** Gets a package that can be considered an entry point for a Vuex app. */
|
||||
private PackageJSON entryPointPackage() {
|
||||
result = getPackageJson(storeRef().getAnImmediateUse().getFile())
|
||||
or
|
||||
|
||||
@@ -60,7 +60,7 @@ module XML {
|
||||
}
|
||||
|
||||
/**
|
||||
* A document from the `libxmljs` library.
|
||||
* Gets a document from the `libxmljs` library.
|
||||
* The API is based on https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/libxmljs/index.d.ts
|
||||
*/
|
||||
private API::Node doc() {
|
||||
@@ -74,7 +74,7 @@ module XML {
|
||||
}
|
||||
|
||||
/**
|
||||
* An `Element` from the `libxmljs` library.
|
||||
* Gets an `Element` from the `libxmljs` library.
|
||||
*/
|
||||
private API::Node element() {
|
||||
result = doc().getMember(["child", "get", "node", "root"]).getReturn()
|
||||
@@ -91,7 +91,7 @@ module XML {
|
||||
}
|
||||
|
||||
/**
|
||||
* An `Attr` from the `libxmljs` library.
|
||||
* Gets an `Attr` from the `libxmljs` library.
|
||||
*/
|
||||
private API::Node attr() {
|
||||
result = element().getMember("attr").getReturn()
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
*/
|
||||
|
||||
private import javascript
|
||||
private import internal.Shared as Shared
|
||||
private import internal.ApiGraphModels as Shared
|
||||
private import internal.ApiGraphModelsSpecific as Specific
|
||||
import Shared::ModelInput as ModelInput
|
||||
import Shared::ModelOutput as ModelOutput
|
||||
|
||||
@@ -39,7 +40,7 @@ private class RemoteFlowSourceFromCsv extends RemoteFlowSource {
|
||||
*/
|
||||
private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) {
|
||||
exists(API::Node predNode, API::Node succNode |
|
||||
ModelOutput::summaryStep(predNode, succNode, kind) and
|
||||
Specific::summaryStep(predNode, succNode, kind) and
|
||||
pred = predNode.getARhs() and
|
||||
succ = succNode.getAnImmediateUse()
|
||||
)
|
||||
|
||||
@@ -56,12 +56,13 @@
|
||||
* the type is related to the `foo` package but is not intended to match a static type.
|
||||
*/
|
||||
|
||||
private import Impl as Impl
|
||||
import AccessPathSyntax
|
||||
private import ApiGraphModelsSpecific as Specific
|
||||
|
||||
private class Unit = Impl::Unit;
|
||||
private class Unit = Specific::Unit;
|
||||
|
||||
private module API = Impl::API;
|
||||
private module API = Specific::API;
|
||||
|
||||
private import Specific::AccessPathSyntax
|
||||
|
||||
/** Module containing hooks for providing input data to be interpreted as a model. */
|
||||
module ModelInput {
|
||||
@@ -230,7 +231,7 @@ string getAPackageAlias(string package) {
|
||||
* Holds if CSV rows involving `package` might be relevant for the analysis of this database.
|
||||
*/
|
||||
private predicate isRelevantPackage(string package) {
|
||||
Impl::isPackageUsed(package)
|
||||
Specific::isPackageUsed(package)
|
||||
or
|
||||
exists(string other |
|
||||
isRelevantPackage(other) and
|
||||
@@ -268,28 +269,25 @@ private class AccessPathRange extends AccessPath::Range {
|
||||
* Gets a successor of `node` in the API graph.
|
||||
*/
|
||||
bindingset[token]
|
||||
private API::Node getSuccessorFromNode(API::Node node, AccessPathToken token) {
|
||||
API::Node getSuccessorFromNode(API::Node node, AccessPathToken token) {
|
||||
// API graphs use the same label for arguments and parameters. An edge originating from a
|
||||
// use-node represents be an argument, and an edge originating from a def-node represents a parameter.
|
||||
// We just map both to the same thing.
|
||||
token.getName() = ["Argument", "Parameter"] and
|
||||
result = node.getParameter(getAnIntFromStringUnbounded(token.getAnArgument()))
|
||||
or
|
||||
token.getName() = "Member" and
|
||||
result = node.getMember(token.getAnArgument())
|
||||
or
|
||||
token.getName() = "ReturnValue" and
|
||||
result = node.getReturn()
|
||||
or
|
||||
// Language-specific tokens
|
||||
result = Impl::getExtraSuccessorFromNode(node, token)
|
||||
result = Specific::getExtraSuccessorFromNode(node, token)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an API-graph successor for the given invocation.
|
||||
*/
|
||||
bindingset[token]
|
||||
private API::Node getSuccessorFromInvoke(API::InvokeNode invoke, AccessPathToken token) {
|
||||
API::Node getSuccessorFromInvoke(Specific::InvokeNode invoke, AccessPathToken token) {
|
||||
token.getName() = "Argument" and
|
||||
(
|
||||
result = invoke.getParameter(getAnIntFromStringUnbounded(token.getAnArgument()))
|
||||
@@ -303,18 +301,18 @@ private API::Node getSuccessorFromInvoke(API::InvokeNode invoke, AccessPathToken
|
||||
result = invoke.getReturn()
|
||||
or
|
||||
// Language-specific tokens
|
||||
result = Impl::getExtraSuccessorFromInvoke(invoke, token)
|
||||
result = Specific::getExtraSuccessorFromInvoke(invoke, token)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `invoke` invokes a call-site filter given by `token`.
|
||||
*/
|
||||
pragma[inline]
|
||||
private predicate invocationMatchesCallSiteFilter(API::InvokeNode invoke, AccessPathToken token) {
|
||||
private predicate invocationMatchesCallSiteFilter(Specific::InvokeNode invoke, AccessPathToken token) {
|
||||
token.getName() = "WithArity" and
|
||||
invoke.getNumArgument() = getAnIntFromStringUnbounded(token.getAnArgument())
|
||||
or
|
||||
Impl::invocationMatchesExtraCallSiteFilter(invoke, token)
|
||||
Specific::invocationMatchesExtraCallSiteFilter(invoke, token)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,10 +322,6 @@ pragma[nomagic]
|
||||
API::Node getNodeFromPath(string package, string type, AccessPath path, int n) {
|
||||
isRelevantFullPath(package, type, path) and
|
||||
(
|
||||
type = "" and
|
||||
n = 0 and
|
||||
result = API::moduleImport(package)
|
||||
or
|
||||
n = 0 and
|
||||
exists(string package2, string type2, AccessPath path2 |
|
||||
typeModel(package, type, package2, type2, path2) and
|
||||
@@ -335,7 +329,7 @@ API::Node getNodeFromPath(string package, string type, AccessPath path, int n) {
|
||||
)
|
||||
or
|
||||
// Language-specific cases, such as handling of global variables
|
||||
result = Impl::getExtraNodeFromPath(package, type, path, n)
|
||||
result = Specific::getExtraNodeFromPath(package, type, path, n)
|
||||
)
|
||||
or
|
||||
result = getSuccessorFromNode(getNodeFromPath(package, type, path, n - 1), path.getToken(n - 1))
|
||||
@@ -355,62 +349,18 @@ API::Node getNodeFromPath(string package, string type, AccessPath path) {
|
||||
*
|
||||
* Unlike `getNodeFromPath`, the `path` may end with one or more call-site filters.
|
||||
*/
|
||||
API::InvokeNode getInvocationFromPath(string package, string type, AccessPath path, int n) {
|
||||
result = getNodeFromPath(package, type, path, n).getAnInvocation()
|
||||
Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPath path, int n) {
|
||||
result = Specific::getAnInvocationOf(getNodeFromPath(package, type, path, n))
|
||||
or
|
||||
result = getInvocationFromPath(package, type, path, n - 1) and
|
||||
invocationMatchesCallSiteFilter(result, path.getToken(n - 1))
|
||||
}
|
||||
|
||||
/** Gets an invocation identified by the given `(package, type, path)` tuple. */
|
||||
API::InvokeNode getInvocationFromPath(string package, string type, AccessPath path) {
|
||||
Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPath path) {
|
||||
result = getInvocationFromPath(package, type, path, path.getNumToken())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a summary edge with the given `input, output, kind` columns have a `package, type, path` tuple
|
||||
* that resolves to `baseNode`.
|
||||
*/
|
||||
private predicate resolvedSummaryBase(
|
||||
API::InvokeNode baseNode, AccessPath input, AccessPath output, string kind
|
||||
) {
|
||||
exists(string package, string type, AccessPath path |
|
||||
summaryModel(package, type, path, input, output, kind) and
|
||||
baseNode = getInvocationFromPath(package, type, path)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `path` is an input or output spec for a summary with the given `base` node.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate relevantInputOutputPath(API::InvokeNode base, AccessPath path) {
|
||||
resolvedSummaryBase(base, path, _, _)
|
||||
or
|
||||
resolvedSummaryBase(base, _, path, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the API node for the first `n` tokens of the given input/output path, evaluated relative to `baseNode`.
|
||||
*/
|
||||
private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPath path, int n) {
|
||||
relevantInputOutputPath(baseNode, path) and
|
||||
(
|
||||
n = 1 and
|
||||
result = getSuccessorFromInvoke(baseNode, path.getToken(0))
|
||||
or
|
||||
result =
|
||||
getSuccessorFromNode(getNodeFromInputOutputPath(baseNode, path, n - 1), path.getToken(n - 1))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the API node for the given input/output path, evaluated relative to `baseNode`.
|
||||
*/
|
||||
private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPath path) {
|
||||
result = getNodeFromInputOutputPath(baseNode, path, path.getNumToken())
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience-predicate for extracting two capture groups at once.
|
||||
*/
|
||||
@@ -519,13 +469,25 @@ module ModelOutput {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a CSV summary contributed the step `pred -> succ` of the given `kind`.
|
||||
* Holds if a relevant CSV summary row has the given `kind`, `input` and `output`.
|
||||
*/
|
||||
predicate summaryStep(API::Node pred, API::Node succ, string kind) {
|
||||
exists(API::InvokeNode base, AccessPath input, AccessPath output |
|
||||
resolvedSummaryBase(base, input, output, kind) and
|
||||
pred = getNodeFromInputOutputPath(base, input) and
|
||||
succ = getNodeFromInputOutputPath(base, output)
|
||||
predicate summaryModel(string input, string output, string kind) {
|
||||
exists(string package |
|
||||
isRelevantPackage(package) and
|
||||
summaryModel(package, _, _, input, output, kind)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a summary edge with the given `input, output, kind` columns have a `package, type, path` tuple
|
||||
* that resolves to `baseNode`.
|
||||
*/
|
||||
predicate resolvedSummaryBase(
|
||||
Specific::InvokeNode baseNode, AccessPath input, AccessPath output, string kind
|
||||
) {
|
||||
exists(string package, string type, AccessPath path |
|
||||
summaryModel(package, type, path, input, output, kind) and
|
||||
baseNode = getInvocationFromPath(package, type, path)
|
||||
)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user