From a3ae304dfea10b29a712715a86f1cbbd585c09d3 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 21 Mar 2024 11:32:23 +0100 Subject: [PATCH 1/2] C++: Handle `getInitializingExpr` in PrintAST --- cpp/ql/lib/semmle/code/cpp/PrintAST.qll | 7 +- .../library-tests/ir/ir/PrintAST.expected | 112 ++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index fa894a8b0fb4..88dce1ce0b4d 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -309,9 +309,12 @@ class ExprNode extends AstNode { override AstNode getChildInternal(int childIndex) { result.getAst() = expr.getChild(childIndex) or + childIndex = max(int index | exists(expr.getChild(index)) or index = 0) + 1 and + result.getAst() = expr.(ConditionDeclExpr).getInitializingExpr() + or exists(int destructorIndex | result.getAst() = expr.getImplicitDestructorCall(destructorIndex) and - childIndex = destructorIndex + max(int index | exists(expr.getChild(index)) or index = 0) + 1 + childIndex = destructorIndex + max(int index | exists(expr.getChild(index)) or index = 0) + 2 ) } @@ -686,6 +689,8 @@ private string getChildAccessorWithoutConversions(Locatable parent, Element chil not namedExprChildPredicates(expr, child, _) and exists(int n | expr.getChild(n) = child and result = "getChild(" + n + ")") or + expr.(ConditionDeclExpr).getInitializingExpr() = child and result = "getInitializingExpr()" + or exists(int n | expr.getImplicitDestructorCall(n) = child and result = "getImplicitDestructorCall(" + n + ")" diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 3c922cd3a5a0..ddf5d8b1f5c2 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -8812,6 +8812,15 @@ ir.cpp: # 976| getVariableAccess(): [VariableAccess] b # 976| Type = [BoolType] bool # 976| ValueCategory = prvalue(load) +# 976| getInitializingExpr(): [LTExpr] ... < ... +# 976| Type = [BoolType] bool +# 976| ValueCategory = prvalue +# 976| getLesserOperand(): [VariableAccess] x +# 976| Type = [IntType] int +# 976| ValueCategory = prvalue(load) +# 976| getGreaterOperand(): [VariableAccess] y +# 976| Type = [IntType] int +# 976| ValueCategory = prvalue(load) # 976| getThen(): [BlockStmt] { ... } # 977| getStmt(0): [ExprStmt] ExprStmt # 977| getExpr(): [AssignExpr] ... = ... @@ -8831,6 +8840,15 @@ ir.cpp: # 979| getVariableAccess(): [VariableAccess] z # 979| Type = [IntType] int # 979| ValueCategory = prvalue(load) +# 979| getInitializingExpr(): [AddExpr] ... + ... +# 979| Type = [IntType] int +# 979| ValueCategory = prvalue +# 979| getLeftOperand(): [VariableAccess] x +# 979| Type = [IntType] int +# 979| ValueCategory = prvalue(load) +# 979| getRightOperand(): [VariableAccess] y +# 979| Type = [IntType] int +# 979| ValueCategory = prvalue(load) # 979| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 979| Conversion = [BoolConversion] conversion to bool # 979| Type = [BoolType] bool @@ -8854,6 +8872,12 @@ ir.cpp: # 982| getVariableAccess(): [VariableAccess] p # 982| Type = [IntPointerType] int * # 982| ValueCategory = prvalue(load) +# 982| getInitializingExpr(): [AddressOfExpr] & ... +# 982| Type = [IntPointerType] int * +# 982| ValueCategory = prvalue +# 982| getOperand(): [VariableAccess] x +# 982| Type = [IntType] int +# 982| ValueCategory = lvalue # 982| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 982| Conversion = [BoolConversion] conversion to bool # 982| Type = [BoolType] bool @@ -8888,6 +8912,15 @@ ir.cpp: # 988| getVariableAccess(): [VariableAccess] b # 988| Type = [BoolType] bool # 988| ValueCategory = prvalue(load) +# 988| getInitializingExpr(): [LTExpr] ... < ... +# 988| Type = [BoolType] bool +# 988| ValueCategory = prvalue +# 988| getLesserOperand(): [VariableAccess] x +# 988| Type = [IntType] int +# 988| ValueCategory = prvalue(load) +# 988| getGreaterOperand(): [VariableAccess] y +# 988| Type = [IntType] int +# 988| ValueCategory = prvalue(load) # 988| getStmt(): [BlockStmt] { ... } # 990| getStmt(1): [WhileStmt] while (...) ... # 990| getCondition(): [ConditionDeclExpr] (condition decl) @@ -8896,6 +8929,15 @@ ir.cpp: # 990| getVariableAccess(): [VariableAccess] z # 990| Type = [IntType] int # 990| ValueCategory = prvalue(load) +# 990| getInitializingExpr(): [AddExpr] ... + ... +# 990| Type = [IntType] int +# 990| ValueCategory = prvalue +# 990| getLeftOperand(): [VariableAccess] x +# 990| Type = [IntType] int +# 990| ValueCategory = prvalue(load) +# 990| getRightOperand(): [VariableAccess] y +# 990| Type = [IntType] int +# 990| ValueCategory = prvalue(load) # 990| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 990| Conversion = [BoolConversion] conversion to bool # 990| Type = [BoolType] bool @@ -8908,6 +8950,12 @@ ir.cpp: # 992| getVariableAccess(): [VariableAccess] p # 992| Type = [IntPointerType] int * # 992| ValueCategory = prvalue(load) +# 992| getInitializingExpr(): [AddressOfExpr] & ... +# 992| Type = [IntPointerType] int * +# 992| ValueCategory = prvalue +# 992| getOperand(): [VariableAccess] x +# 992| Type = [IntType] int +# 992| ValueCategory = lvalue # 992| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 992| Conversion = [BoolConversion] conversion to bool # 992| Type = [BoolType] bool @@ -14780,6 +14828,9 @@ ir.cpp: # 1816| getVariableAccess(): [VariableAccess] w2 # 1816| Type = [IntType] int # 1816| ValueCategory = prvalue(load) +# 1816| getInitializingExpr(): [VariableAccess] w +# 1816| Type = [IntType] int +# 1816| ValueCategory = prvalue(load) # 1816| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 1816| Conversion = [BoolConversion] conversion to bool # 1816| Type = [BoolType] bool @@ -14815,6 +14866,9 @@ ir.cpp: # 1820| getVariableAccess(): [VariableAccess] v2 # 1820| Type = [IntType] int # 1820| ValueCategory = prvalue(load) +# 1820| getInitializingExpr(): [VariableAccess] v +# 1820| Type = [IntType] int +# 1820| ValueCategory = prvalue(load) # 1820| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 1820| Conversion = [BoolConversion] conversion to bool # 1820| Type = [BoolType] bool @@ -14875,6 +14929,9 @@ ir.cpp: # 1829| getVariableAccess(): [VariableAccess] z2 # 1829| Type = [IntType] int # 1829| ValueCategory = prvalue(load) +# 1829| getInitializingExpr(): [VariableAccess] z +# 1829| Type = [IntType] int +# 1829| ValueCategory = prvalue(load) # 1829| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 1829| Conversion = [BoolConversion] conversion to bool # 1829| Type = [BoolType] bool @@ -14991,6 +15048,9 @@ ir.cpp: # 1846| getVariableAccess(): [VariableAccess] w2 # 1846| Type = [IntType] int # 1846| ValueCategory = prvalue(load) +# 1846| getInitializingExpr(): [VariableAccess] w +# 1846| Type = [IntType] int +# 1846| ValueCategory = prvalue(load) # 1846| getStmt(): [BlockStmt] { ... } # 1847| getStmt(0): [SwitchCase] default: # 1848| getStmt(1): [ExprStmt] ExprStmt @@ -15023,6 +15083,9 @@ ir.cpp: # 1851| getVariableAccess(): [VariableAccess] v2 # 1851| Type = [IntType] int # 1851| ValueCategory = prvalue(load) +# 1851| getInitializingExpr(): [VariableAccess] v +# 1851| Type = [IntType] int +# 1851| ValueCategory = prvalue(load) # 1851| getStmt(): [BlockStmt] { ... } # 1852| getStmt(0): [SwitchCase] default: # 1853| getStmt(1): [ExprStmt] ExprStmt @@ -15077,6 +15140,9 @@ ir.cpp: # 1862| getVariableAccess(): [VariableAccess] z2 # 1862| Type = [IntType] int # 1862| ValueCategory = prvalue(load) +# 1862| getInitializingExpr(): [VariableAccess] z +# 1862| Type = [IntType] int +# 1862| ValueCategory = prvalue(load) # 1862| getStmt(): [BlockStmt] { ... } # 1863| getStmt(0): [SwitchCase] default: # 1864| getStmt(1): [ExprStmt] ExprStmt @@ -17048,6 +17114,10 @@ ir.cpp: # 2169| getQualifier(): [VariableAccess] b # 2169| Type = [Struct] HasOperatorBool # 2169| ValueCategory = prvalue(load) +# 2169| getInitializingExpr(): [Literal] 0 +# 2169| Type = [Struct] HasOperatorBool +# 2169| Value = [Literal] 0 +# 2169| ValueCategory = prvalue # 2169| getThen(): [BlockStmt] { ... } # 2170| getStmt(1): [ReturnStmt] return ... # 2172| [CopyAssignmentOperator] ClassWithDestructor& ClassWithDestructor::operator=(ClassWithDestructor const&) @@ -18650,6 +18720,12 @@ ir.cpp: # 2318| getQualifier(): [VariableAccess] B # 2318| Type = [Class] Bool # 2318| ValueCategory = prvalue(load) +# 2318| getInitializingExpr(): [ConstructorCall] call to Bool +# 2318| Type = [VoidType] void +# 2318| ValueCategory = prvalue +# 2318| getArgument(0): [VariableAccess] b +# 2318| Type = [BoolType] bool +# 2318| ValueCategory = prvalue(load) # 2318| getThen(): [BlockStmt] { ... } # 2319| getStmt(0): [DeclStmt] declaration # 2319| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1 @@ -18731,6 +18807,12 @@ ir.cpp: # 2334| getQualifier(): [VariableAccess] B # 2334| Type = [Class] Bool # 2334| ValueCategory = prvalue(load) +# 2334| getInitializingExpr(): [ConstructorCall] call to Bool +# 2334| Type = [VoidType] void +# 2334| ValueCategory = prvalue +# 2334| getArgument(0): [VariableAccess] b +# 2334| Type = [BoolType] bool +# 2334| ValueCategory = prvalue(load) # 2334| getStmt(): [BlockStmt] { ... } # 2335| getStmt(0): [ExprStmt] ExprStmt # 2335| getExpr(): [AssignExpr] ... = ... @@ -19678,6 +19760,21 @@ ir.cpp: # 2397| getVariableAccess(): [VariableAccess] x # 2397| Type = [PlainCharType] char # 2397| ValueCategory = prvalue(load) +# 2397| getInitializingExpr(): [FunctionCall] call to get_x +# 2397| Type = [PlainCharType] char +# 2397| ValueCategory = prvalue +# 2397| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2397| Type = [VoidType] void +# 2397| ValueCategory = prvalue +# 2397| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2397| Type = [VoidType] void +# 2397| ValueCategory = prvalue +# 2397| getQualifier(): [ReuseExpr] reuse of temporary object +# 2397| Type = [Class] ClassWithDestructor +# 2397| ValueCategory = xvalue +# 2397| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2397| Type = [Class] ClassWithDestructor +# 2397| ValueCategory = prvalue(load) # 2397| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 2397| Conversion = [BoolConversion] conversion to bool # 2397| Type = [BoolType] bool @@ -19749,6 +19846,21 @@ ir.cpp: # 2406| getVariableAccess(): [VariableAccess] x # 2406| Type = [PlainCharType] char # 2406| ValueCategory = prvalue(load) +# 2406| getInitializingExpr(): [FunctionCall] call to get_x +# 2406| Type = [PlainCharType] char +# 2406| ValueCategory = prvalue +# 2406| getQualifier(): [ConstructorCall] call to ClassWithDestructor +# 2406| Type = [VoidType] void +# 2406| ValueCategory = prvalue +# 2406| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor +# 2406| Type = [VoidType] void +# 2406| ValueCategory = prvalue +# 2406| getQualifier(): [ReuseExpr] reuse of temporary object +# 2406| Type = [Class] ClassWithDestructor +# 2406| ValueCategory = xvalue +# 2406| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object +# 2406| Type = [Class] ClassWithDestructor +# 2406| ValueCategory = prvalue(load) # 2406| getVariableAccess().getFullyConverted(): [CStyleCast] (int)... # 2406| Conversion = [IntegralConversion] integral conversion # 2406| Type = [IntType] int From 4c4ebd907e51be023d59c50792a3047aec46f6dd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 21 Mar 2024 11:54:29 +0100 Subject: [PATCH 2/2] C++: Update more expected test results --- cpp/ql/test/examples/expressions/PrintAST.expected | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cpp/ql/test/examples/expressions/PrintAST.expected b/cpp/ql/test/examples/expressions/PrintAST.expected index 86aa1e364146..4aefbff5c554 100644 --- a/cpp/ql/test/examples/expressions/PrintAST.expected +++ b/cpp/ql/test/examples/expressions/PrintAST.expected @@ -105,10 +105,24 @@ ConditionDecl.cpp: # 3| getVariableAccess(): [VariableAccess] k # 3| Type = [IntType] int # 3| ValueCategory = prvalue(load) +# 3| getInitializingExpr(): [LTExpr] ... < ... +# 3| Type = [BoolType] bool +# 3| ValueCategory = prvalue +# 3| getLesserOperand(): [VariableAccess] j +# 3| Type = [IntType] int +# 3| ValueCategory = prvalue(load) +# 3| getGreaterOperand(): [Literal] 5 +# 3| Type = [IntType] int +# 3| Value = [Literal] 5 +# 3| ValueCategory = prvalue # 3| getVariableAccess().getFullyConverted(): [CStyleCast] (bool)... # 3| Conversion = [BoolConversion] conversion to bool # 3| Type = [BoolType] bool # 3| ValueCategory = prvalue +# 3| getInitializingExpr().getFullyConverted(): [CStyleCast] (int)... +# 3| Conversion = [IntegralConversion] integral conversion +# 3| Type = [IntType] int +# 3| ValueCategory = prvalue # 3| getStmt(): [BlockStmt] { ... } # 5| getStmt(2): [ReturnStmt] return ... ConstructorCall.cpp: