From 799f33eb3aed8e03dd4e4330e8250ce3e0ffd800 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 14:08:29 +0200 Subject: [PATCH 1/7] C++: Add more postfix-crement tests --- .../library-tests/dataflow/asExpr/test.cpp | 8 + .../library-tests/ir/ir/PrintAST.expected | 174 ++++++++++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 109 +++++++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 17 ++ .../test/library-tests/ir/ir/raw_ir.expected | 107 +++++++++++ 5 files changed, 415 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp b/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp index 859271087fbc..5f305ed21734 100644 --- a/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp @@ -42,8 +42,16 @@ void test_aggregate_literal() { void test_postfix_crement(int *p, int q) { p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr=p asIndirectExpr=p q++; // $ asExpr="... ++" asExpr=q + (p++); // $ numberOfNodes="... ++: 2" numberOfIndirectNodes="... ++: 2" asExpr="... ++" asIndirectExpr="... ++" MISSING: asExpr=p asIndirectExpr=p + (q++); // $ numberOfNodes="... ++: 2" asExpr="... ++" MISSING: asExpr=q (void)(p++); // $ numberOfNodes="... ++: 2" asExpr="... ++" numberOfIndirectNodes="... ++: 2" asIndirectExpr="... ++" MISSING: asExpr=p asIndirectExpr=p (void)(q++); // $ numberOfNodes="... ++: 2" asExpr="... ++" MISSING: asExpr=q + (void)p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr=p asIndirectExpr=p + (void)q++; // $ asExpr="... ++" asExpr=q int *p1 = p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)" int q1 = q++; // $ asExpr="... ++" asExpr="q(... ++)" + (int*)(p++); // $ numberOfIndirectNodes="... ++: 2" asExpr="... ++" asIndirectExpr="... ++" MISSING: asExpr="p(... ++)" asIndirectExpr="p(*... ++)" + (int)(q++); // $ asExpr="... ++" MISSING: asExpr="q(... ++)" + int *p2 = (int*)(p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)" + int q2 = (int)(q++); // $ asExpr="... ++" asExpr="q(... ++)" } diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 8f280c89764c..a530c429072e 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -24262,6 +24262,180 @@ ir.cpp: # 2725| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference) # 2725| Type = [PlainCharType] char # 2725| ValueCategory = prvalue(load) +# 2728| [TopLevelFunction] void test_postfix_crement(int*, int) +# 2728| : +# 2728| getParameter(0): [Parameter] p +# 2728| Type = [IntPointerType] int * +# 2728| getParameter(1): [Parameter] q +# 2728| Type = [IntType] int +# 2728| getEntryPoint(): [BlockStmt] { ... } +# 2729| getStmt(0): [ExprStmt] ExprStmt +# 2729| getExpr(): [PostfixIncrExpr] ... ++ +# 2729| Type = [IntPointerType] int * +# 2729| ValueCategory = prvalue +# 2729| getOperand(): [VariableAccess] p +# 2729| Type = [IntPointerType] int * +# 2729| ValueCategory = lvalue +# 2730| getStmt(1): [ExprStmt] ExprStmt +# 2730| getExpr(): [PostfixIncrExpr] ... ++ +# 2730| Type = [IntType] int +# 2730| ValueCategory = prvalue +# 2730| getOperand(): [VariableAccess] q +# 2730| Type = [IntType] int +# 2730| ValueCategory = lvalue +# 2731| getStmt(2): [ExprStmt] ExprStmt +# 2731| getExpr(): [PostfixIncrExpr] ... ++ +# 2731| Type = [IntPointerType] int * +# 2731| ValueCategory = prvalue +# 2731| getOperand(): [VariableAccess] p +# 2731| Type = [IntPointerType] int * +# 2731| ValueCategory = lvalue +# 2731| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2731| Type = [IntPointerType] int * +# 2731| ValueCategory = prvalue +# 2732| getStmt(3): [ExprStmt] ExprStmt +# 2732| getExpr(): [PostfixIncrExpr] ... ++ +# 2732| Type = [IntType] int +# 2732| ValueCategory = prvalue +# 2732| getOperand(): [VariableAccess] q +# 2732| Type = [IntType] int +# 2732| ValueCategory = lvalue +# 2732| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2732| Type = [IntType] int +# 2732| ValueCategory = prvalue +# 2733| getStmt(4): [ExprStmt] ExprStmt +# 2733| getExpr(): [PostfixIncrExpr] ... ++ +# 2733| Type = [IntPointerType] int * +# 2733| ValueCategory = prvalue +# 2733| getOperand(): [VariableAccess] p +# 2733| Type = [IntPointerType] int * +# 2733| ValueCategory = lvalue +# 2733| getExpr().getFullyConverted(): [CStyleCast] (void)... +# 2733| Conversion = [VoidConversion] conversion to void +# 2733| Type = [VoidType] void +# 2733| ValueCategory = prvalue +# 2733| getExpr(): [ParenthesisExpr] (...) +# 2733| Type = [IntPointerType] int * +# 2733| ValueCategory = prvalue +# 2734| getStmt(5): [ExprStmt] ExprStmt +# 2734| getExpr(): [PostfixIncrExpr] ... ++ +# 2734| Type = [IntType] int +# 2734| ValueCategory = prvalue +# 2734| getOperand(): [VariableAccess] q +# 2734| Type = [IntType] int +# 2734| ValueCategory = lvalue +# 2734| getExpr().getFullyConverted(): [CStyleCast] (void)... +# 2734| Conversion = [VoidConversion] conversion to void +# 2734| Type = [VoidType] void +# 2734| ValueCategory = prvalue +# 2734| getExpr(): [ParenthesisExpr] (...) +# 2734| Type = [IntType] int +# 2734| ValueCategory = prvalue +# 2735| getStmt(6): [ExprStmt] ExprStmt +# 2735| getExpr(): [PostfixIncrExpr] ... ++ +# 2735| Type = [IntPointerType] int * +# 2735| ValueCategory = prvalue +# 2735| getOperand(): [VariableAccess] p +# 2735| Type = [IntPointerType] int * +# 2735| ValueCategory = lvalue +# 2735| getExpr().getFullyConverted(): [CStyleCast] (void)... +# 2735| Conversion = [VoidConversion] conversion to void +# 2735| Type = [VoidType] void +# 2735| ValueCategory = prvalue +# 2736| getStmt(7): [ExprStmt] ExprStmt +# 2736| getExpr(): [PostfixIncrExpr] ... ++ +# 2736| Type = [IntType] int +# 2736| ValueCategory = prvalue +# 2736| getOperand(): [VariableAccess] q +# 2736| Type = [IntType] int +# 2736| ValueCategory = lvalue +# 2736| getExpr().getFullyConverted(): [CStyleCast] (void)... +# 2736| Conversion = [VoidConversion] conversion to void +# 2736| Type = [VoidType] void +# 2736| ValueCategory = prvalue +# 2737| getStmt(8): [DeclStmt] declaration +# 2737| getDeclarationEntry(0): [VariableDeclarationEntry] definition of p1 +# 2737| Type = [IntPointerType] int * +# 2737| getVariable().getInitializer(): [Initializer] initializer for p1 +# 2737| getExpr(): [PostfixIncrExpr] ... ++ +# 2737| Type = [IntPointerType] int * +# 2737| ValueCategory = prvalue +# 2737| getOperand(): [VariableAccess] p +# 2737| Type = [IntPointerType] int * +# 2737| ValueCategory = lvalue +# 2738| getStmt(9): [DeclStmt] declaration +# 2738| getDeclarationEntry(0): [VariableDeclarationEntry] definition of q1 +# 2738| Type = [IntType] int +# 2738| getVariable().getInitializer(): [Initializer] initializer for q1 +# 2738| getExpr(): [PostfixIncrExpr] ... ++ +# 2738| Type = [IntType] int +# 2738| ValueCategory = prvalue +# 2738| getOperand(): [VariableAccess] q +# 2738| Type = [IntType] int +# 2738| ValueCategory = lvalue +# 2739| getStmt(10): [ExprStmt] ExprStmt +# 2739| getExpr(): [PostfixIncrExpr] ... ++ +# 2739| Type = [IntPointerType] int * +# 2739| ValueCategory = prvalue +# 2739| getOperand(): [VariableAccess] p +# 2739| Type = [IntPointerType] int * +# 2739| ValueCategory = lvalue +# 2739| getExpr().getFullyConverted(): [CStyleCast] (int *)... +# 2739| Conversion = [PointerConversion] pointer conversion +# 2739| Type = [IntPointerType] int * +# 2739| ValueCategory = prvalue +# 2739| getExpr(): [ParenthesisExpr] (...) +# 2739| Type = [IntPointerType] int * +# 2739| ValueCategory = prvalue +# 2740| getStmt(11): [ExprStmt] ExprStmt +# 2740| getExpr(): [PostfixIncrExpr] ... ++ +# 2740| Type = [IntType] int +# 2740| ValueCategory = prvalue +# 2740| getOperand(): [VariableAccess] q +# 2740| Type = [IntType] int +# 2740| ValueCategory = lvalue +# 2740| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2740| Conversion = [IntegralConversion] integral conversion +# 2740| Type = [IntType] int +# 2740| ValueCategory = prvalue +# 2740| getExpr(): [ParenthesisExpr] (...) +# 2740| Type = [IntType] int +# 2740| ValueCategory = prvalue +# 2741| getStmt(12): [DeclStmt] declaration +# 2741| getDeclarationEntry(0): [VariableDeclarationEntry] definition of p2 +# 2741| Type = [IntPointerType] int * +# 2741| getVariable().getInitializer(): [Initializer] initializer for p2 +# 2741| getExpr(): [PostfixIncrExpr] ... ++ +# 2741| Type = [IntPointerType] int * +# 2741| ValueCategory = prvalue +# 2741| getOperand(): [VariableAccess] p +# 2741| Type = [IntPointerType] int * +# 2741| ValueCategory = lvalue +# 2741| getExpr().getFullyConverted(): [CStyleCast] (int *)... +# 2741| Conversion = [PointerConversion] pointer conversion +# 2741| Type = [IntPointerType] int * +# 2741| ValueCategory = prvalue +# 2741| getExpr(): [ParenthesisExpr] (...) +# 2741| Type = [IntPointerType] int * +# 2741| ValueCategory = prvalue +# 2742| getStmt(13): [DeclStmt] declaration +# 2742| getDeclarationEntry(0): [VariableDeclarationEntry] definition of q2 +# 2742| Type = [IntType] int +# 2742| getVariable().getInitializer(): [Initializer] initializer for q2 +# 2742| getExpr(): [PostfixIncrExpr] ... ++ +# 2742| Type = [IntType] int +# 2742| ValueCategory = prvalue +# 2742| getOperand(): [VariableAccess] q +# 2742| Type = [IntType] int +# 2742| ValueCategory = lvalue +# 2742| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2742| Conversion = [IntegralConversion] integral conversion +# 2742| Type = [IntType] int +# 2742| ValueCategory = prvalue +# 2742| getExpr(): [ParenthesisExpr] (...) +# 2742| Type = [IntType] int +# 2742| ValueCategory = prvalue +# 2743| getStmt(14): [ReturnStmt] return ... ir23.cpp: # 1| [TopLevelFunction] bool consteval_1() # 1| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 575631ab0417..5b5e6a0585f8 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -20156,6 +20156,115 @@ ir.cpp: # 2724| v2724_12(void) = AliasedUse : ~m2725_8 # 2724| v2724_13(void) = ExitFunction : +# 2728| void test_postfix_crement(int*, int) +# 2728| Block 0 +# 2728| v2728_1(void) = EnterFunction : +# 2728| m2728_2(unknown) = AliasedDefinition : +# 2728| m2728_3(unknown) = InitializeNonLocal : +# 2728| m2728_4(unknown) = Chi : total:m2728_2, partial:m2728_3 +# 2728| r2728_5(glval) = VariableAddress[p] : +# 2728| m2728_6(int *) = InitializeParameter[p] : &:r2728_5 +# 2728| r2728_7(int *) = Load[p] : &:r2728_5, m2728_6 +# 2728| m2728_8(unknown) = InitializeIndirection[p] : &:r2728_7 +# 2728| m2728_9(unknown) = Chi : total:m2728_4, partial:m2728_8 +# 2728| r2728_10(glval) = VariableAddress[q] : +# 2728| m2728_11(int) = InitializeParameter[q] : &:r2728_10 +# 2729| r2729_1(glval) = VariableAddress[p] : +# 2729| r2729_2(int *) = Load[p] : &:r2729_1, m2728_6 +# 2729| r2729_3(int) = Constant[1] : +# 2729| r2729_4(int *) = PointerAdd[4] : r2729_2, r2729_3 +# 2729| m2729_5(int *) = Store[p] : &:r2729_1, r2729_4 +# 2730| r2730_1(glval) = VariableAddress[q] : +# 2730| r2730_2(int) = Load[q] : &:r2730_1, m2728_11 +# 2730| r2730_3(int) = Constant[1] : +# 2730| r2730_4(int) = Add : r2730_2, r2730_3 +# 2730| m2730_5(int) = Store[q] : &:r2730_1, r2730_4 +# 2731| r2731_1(glval) = VariableAddress[p] : +# 2731| r2731_2(int *) = Load[p] : &:r2731_1, m2729_5 +# 2731| r2731_3(int) = Constant[1] : +# 2731| r2731_4(int *) = PointerAdd[4] : r2731_2, r2731_3 +# 2731| m2731_5(int *) = Store[p] : &:r2731_1, r2731_4 +# 2732| r2732_1(glval) = VariableAddress[q] : +# 2732| r2732_2(int) = Load[q] : &:r2732_1, m2730_5 +# 2732| r2732_3(int) = Constant[1] : +# 2732| r2732_4(int) = Add : r2732_2, r2732_3 +# 2732| m2732_5(int) = Store[q] : &:r2732_1, r2732_4 +# 2733| r2733_1(glval) = VariableAddress[p] : +# 2733| r2733_2(int *) = Load[p] : &:r2733_1, m2731_5 +# 2733| r2733_3(int) = Constant[1] : +# 2733| r2733_4(int *) = PointerAdd[4] : r2733_2, r2733_3 +# 2733| m2733_5(int *) = Store[p] : &:r2733_1, r2733_4 +# 2733| v2733_6(void) = Convert : r2733_2 +# 2734| r2734_1(glval) = VariableAddress[q] : +# 2734| r2734_2(int) = Load[q] : &:r2734_1, m2732_5 +# 2734| r2734_3(int) = Constant[1] : +# 2734| r2734_4(int) = Add : r2734_2, r2734_3 +# 2734| m2734_5(int) = Store[q] : &:r2734_1, r2734_4 +# 2734| v2734_6(void) = Convert : r2734_2 +# 2735| r2735_1(glval) = VariableAddress[p] : +# 2735| r2735_2(int *) = Load[p] : &:r2735_1, m2733_5 +# 2735| r2735_3(int) = Constant[1] : +# 2735| r2735_4(int *) = PointerAdd[4] : r2735_2, r2735_3 +# 2735| m2735_5(int *) = Store[p] : &:r2735_1, r2735_4 +# 2735| v2735_6(void) = Convert : r2735_2 +# 2736| r2736_1(glval) = VariableAddress[q] : +# 2736| r2736_2(int) = Load[q] : &:r2736_1, m2734_5 +# 2736| r2736_3(int) = Constant[1] : +# 2736| r2736_4(int) = Add : r2736_2, r2736_3 +# 2736| m2736_5(int) = Store[q] : &:r2736_1, r2736_4 +# 2736| v2736_6(void) = Convert : r2736_2 +# 2737| r2737_1(glval) = VariableAddress[p1] : +# 2737| r2737_2(glval) = VariableAddress[p] : +# 2737| r2737_3(int *) = Load[p] : &:r2737_2, m2735_5 +# 2737| r2737_4(int) = Constant[1] : +# 2737| r2737_5(int *) = PointerAdd[4] : r2737_3, r2737_4 +# 2737| m2737_6(int *) = Store[p] : &:r2737_2, r2737_5 +# 2737| r2737_7(int *) = CopyValue : r2737_3 +# 2737| m2737_8(int *) = Store[p1] : &:r2737_1, r2737_7 +# 2738| r2738_1(glval) = VariableAddress[q1] : +# 2738| r2738_2(glval) = VariableAddress[q] : +# 2738| r2738_3(int) = Load[q] : &:r2738_2, m2736_5 +# 2738| r2738_4(int) = Constant[1] : +# 2738| r2738_5(int) = Add : r2738_3, r2738_4 +# 2738| m2738_6(int) = Store[q] : &:r2738_2, r2738_5 +# 2738| r2738_7(int) = CopyValue : r2738_3 +# 2738| m2738_8(int) = Store[q1] : &:r2738_1, r2738_7 +# 2739| r2739_1(glval) = VariableAddress[p] : +# 2739| r2739_2(int *) = Load[p] : &:r2739_1, m2737_6 +# 2739| r2739_3(int) = Constant[1] : +# 2739| r2739_4(int *) = PointerAdd[4] : r2739_2, r2739_3 +# 2739| m2739_5(int *) = Store[p] : &:r2739_1, r2739_4 +# 2739| r2739_6(int *) = Convert : r2739_2 +# 2740| r2740_1(glval) = VariableAddress[q] : +# 2740| r2740_2(int) = Load[q] : &:r2740_1, m2738_6 +# 2740| r2740_3(int) = Constant[1] : +# 2740| r2740_4(int) = Add : r2740_2, r2740_3 +# 2740| m2740_5(int) = Store[q] : &:r2740_1, r2740_4 +# 2740| r2740_6(int) = Convert : r2740_2 +# 2741| r2741_1(glval) = VariableAddress[p2] : +# 2741| r2741_2(glval) = VariableAddress[p] : +# 2741| r2741_3(int *) = Load[p] : &:r2741_2, m2739_5 +# 2741| r2741_4(int) = Constant[1] : +# 2741| r2741_5(int *) = PointerAdd[4] : r2741_3, r2741_4 +# 2741| m2741_6(int *) = Store[p] : &:r2741_2, r2741_5 +# 2741| r2741_7(int *) = CopyValue : r2741_3 +# 2741| r2741_8(int *) = Convert : r2741_7 +# 2741| m2741_9(int *) = Store[p2] : &:r2741_1, r2741_8 +# 2742| r2742_1(glval) = VariableAddress[q2] : +# 2742| r2742_2(glval) = VariableAddress[q] : +# 2742| r2742_3(int) = Load[q] : &:r2742_2, m2740_5 +# 2742| r2742_4(int) = Constant[1] : +# 2742| r2742_5(int) = Add : r2742_3, r2742_4 +# 2742| m2742_6(int) = Store[q] : &:r2742_2, r2742_5 +# 2742| r2742_7(int) = CopyValue : r2742_3 +# 2742| r2742_8(int) = Convert : r2742_7 +# 2742| m2742_9(int) = Store[q2] : &:r2742_1, r2742_8 +# 2743| v2743_1(void) = NoOp : +# 2728| v2728_12(void) = ReturnIndirection[p] : &:r2728_7, m2728_8 +# 2728| v2728_13(void) = ReturnVoid : +# 2728| v2728_14(void) = AliasedUse : ~m2728_9 +# 2728| v2728_15(void) = ExitFunction : + ir23.cpp: # 1| bool consteval_1() # 1| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 67db690dc54b..92566968e6ea 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2725,4 +2725,21 @@ char UseBracketOperator(const WithBracketOperator x, int i) { return x[i]; } +void test_postfix_crement(int *p, int q) { + p++; + q++; + (p++); + (q++); + (void)(p++); + (void)(q++); + (void)p++; + (void)q++; + int *p1 = p++; + int q1 = q++; + (int*)(p++); + (int)(q++); + int *p2 = (int*)(p++); + int q2 = (int)(q++); +} + // semmle-extractor-options: -std=c++20 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index e57a3bc11b5e..67e480d44ab2 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -18317,6 +18317,113 @@ ir.cpp: # 2724| v2724_10(void) = AliasedUse : ~m? # 2724| v2724_11(void) = ExitFunction : +# 2728| void test_postfix_crement(int*, int) +# 2728| Block 0 +# 2728| v2728_1(void) = EnterFunction : +# 2728| mu2728_2(unknown) = AliasedDefinition : +# 2728| mu2728_3(unknown) = InitializeNonLocal : +# 2728| r2728_4(glval) = VariableAddress[p] : +# 2728| mu2728_5(int *) = InitializeParameter[p] : &:r2728_4 +# 2728| r2728_6(int *) = Load[p] : &:r2728_4, ~m? +# 2728| mu2728_7(unknown) = InitializeIndirection[p] : &:r2728_6 +# 2728| r2728_8(glval) = VariableAddress[q] : +# 2728| mu2728_9(int) = InitializeParameter[q] : &:r2728_8 +# 2729| r2729_1(glval) = VariableAddress[p] : +# 2729| r2729_2(int *) = Load[p] : &:r2729_1, ~m? +# 2729| r2729_3(int) = Constant[1] : +# 2729| r2729_4(int *) = PointerAdd[4] : r2729_2, r2729_3 +# 2729| mu2729_5(int *) = Store[p] : &:r2729_1, r2729_4 +# 2730| r2730_1(glval) = VariableAddress[q] : +# 2730| r2730_2(int) = Load[q] : &:r2730_1, ~m? +# 2730| r2730_3(int) = Constant[1] : +# 2730| r2730_4(int) = Add : r2730_2, r2730_3 +# 2730| mu2730_5(int) = Store[q] : &:r2730_1, r2730_4 +# 2731| r2731_1(glval) = VariableAddress[p] : +# 2731| r2731_2(int *) = Load[p] : &:r2731_1, ~m? +# 2731| r2731_3(int) = Constant[1] : +# 2731| r2731_4(int *) = PointerAdd[4] : r2731_2, r2731_3 +# 2731| mu2731_5(int *) = Store[p] : &:r2731_1, r2731_4 +# 2732| r2732_1(glval) = VariableAddress[q] : +# 2732| r2732_2(int) = Load[q] : &:r2732_1, ~m? +# 2732| r2732_3(int) = Constant[1] : +# 2732| r2732_4(int) = Add : r2732_2, r2732_3 +# 2732| mu2732_5(int) = Store[q] : &:r2732_1, r2732_4 +# 2733| r2733_1(glval) = VariableAddress[p] : +# 2733| r2733_2(int *) = Load[p] : &:r2733_1, ~m? +# 2733| r2733_3(int) = Constant[1] : +# 2733| r2733_4(int *) = PointerAdd[4] : r2733_2, r2733_3 +# 2733| mu2733_5(int *) = Store[p] : &:r2733_1, r2733_4 +# 2733| v2733_6(void) = Convert : r2733_2 +# 2734| r2734_1(glval) = VariableAddress[q] : +# 2734| r2734_2(int) = Load[q] : &:r2734_1, ~m? +# 2734| r2734_3(int) = Constant[1] : +# 2734| r2734_4(int) = Add : r2734_2, r2734_3 +# 2734| mu2734_5(int) = Store[q] : &:r2734_1, r2734_4 +# 2734| v2734_6(void) = Convert : r2734_2 +# 2735| r2735_1(glval) = VariableAddress[p] : +# 2735| r2735_2(int *) = Load[p] : &:r2735_1, ~m? +# 2735| r2735_3(int) = Constant[1] : +# 2735| r2735_4(int *) = PointerAdd[4] : r2735_2, r2735_3 +# 2735| mu2735_5(int *) = Store[p] : &:r2735_1, r2735_4 +# 2735| v2735_6(void) = Convert : r2735_2 +# 2736| r2736_1(glval) = VariableAddress[q] : +# 2736| r2736_2(int) = Load[q] : &:r2736_1, ~m? +# 2736| r2736_3(int) = Constant[1] : +# 2736| r2736_4(int) = Add : r2736_2, r2736_3 +# 2736| mu2736_5(int) = Store[q] : &:r2736_1, r2736_4 +# 2736| v2736_6(void) = Convert : r2736_2 +# 2737| r2737_1(glval) = VariableAddress[p1] : +# 2737| r2737_2(glval) = VariableAddress[p] : +# 2737| r2737_3(int *) = Load[p] : &:r2737_2, ~m? +# 2737| r2737_4(int) = Constant[1] : +# 2737| r2737_5(int *) = PointerAdd[4] : r2737_3, r2737_4 +# 2737| mu2737_6(int *) = Store[p] : &:r2737_2, r2737_5 +# 2737| r2737_7(int *) = CopyValue : r2737_3 +# 2737| mu2737_8(int *) = Store[p1] : &:r2737_1, r2737_7 +# 2738| r2738_1(glval) = VariableAddress[q1] : +# 2738| r2738_2(glval) = VariableAddress[q] : +# 2738| r2738_3(int) = Load[q] : &:r2738_2, ~m? +# 2738| r2738_4(int) = Constant[1] : +# 2738| r2738_5(int) = Add : r2738_3, r2738_4 +# 2738| mu2738_6(int) = Store[q] : &:r2738_2, r2738_5 +# 2738| r2738_7(int) = CopyValue : r2738_3 +# 2738| mu2738_8(int) = Store[q1] : &:r2738_1, r2738_7 +# 2739| r2739_1(glval) = VariableAddress[p] : +# 2739| r2739_2(int *) = Load[p] : &:r2739_1, ~m? +# 2739| r2739_3(int) = Constant[1] : +# 2739| r2739_4(int *) = PointerAdd[4] : r2739_2, r2739_3 +# 2739| mu2739_5(int *) = Store[p] : &:r2739_1, r2739_4 +# 2739| r2739_6(int *) = Convert : r2739_2 +# 2740| r2740_1(glval) = VariableAddress[q] : +# 2740| r2740_2(int) = Load[q] : &:r2740_1, ~m? +# 2740| r2740_3(int) = Constant[1] : +# 2740| r2740_4(int) = Add : r2740_2, r2740_3 +# 2740| mu2740_5(int) = Store[q] : &:r2740_1, r2740_4 +# 2740| r2740_6(int) = Convert : r2740_2 +# 2741| r2741_1(glval) = VariableAddress[p2] : +# 2741| r2741_2(glval) = VariableAddress[p] : +# 2741| r2741_3(int *) = Load[p] : &:r2741_2, ~m? +# 2741| r2741_4(int) = Constant[1] : +# 2741| r2741_5(int *) = PointerAdd[4] : r2741_3, r2741_4 +# 2741| mu2741_6(int *) = Store[p] : &:r2741_2, r2741_5 +# 2741| r2741_7(int *) = CopyValue : r2741_3 +# 2741| r2741_8(int *) = Convert : r2741_7 +# 2741| mu2741_9(int *) = Store[p2] : &:r2741_1, r2741_8 +# 2742| r2742_1(glval) = VariableAddress[q2] : +# 2742| r2742_2(glval) = VariableAddress[q] : +# 2742| r2742_3(int) = Load[q] : &:r2742_2, ~m? +# 2742| r2742_4(int) = Constant[1] : +# 2742| r2742_5(int) = Add : r2742_3, r2742_4 +# 2742| mu2742_6(int) = Store[q] : &:r2742_2, r2742_5 +# 2742| r2742_7(int) = CopyValue : r2742_3 +# 2742| r2742_8(int) = Convert : r2742_7 +# 2742| mu2742_9(int) = Store[q2] : &:r2742_1, r2742_8 +# 2743| v2743_1(void) = NoOp : +# 2728| v2728_10(void) = ReturnIndirection[p] : &:r2728_6, ~m? +# 2728| v2728_11(void) = ReturnVoid : +# 2728| v2728_12(void) = AliasedUse : ~m? +# 2728| v2728_13(void) = ExitFunction : + ir23.cpp: # 1| bool consteval_1() # 1| Block 0 From e68d10119b3246f17fda9278370cb4450c7f6939 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 14:09:09 +0200 Subject: [PATCH 2/7] C++: Fix typo in comment --- cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ExprNodes.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ExprNodes.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ExprNodes.qll index 42ab60eced78..6d69dd11e80b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ExprNodes.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ExprNodes.qll @@ -151,7 +151,7 @@ private module Cached { ) or // Similarly for `i++` and `++i` we pretend that the generated - // `StoreInstruction` is contains the result of the expression even though + // `StoreInstruction` contains the result of the expression even though // this isn't totally aligned with the C/C++ standard. exists(TranslatedCrementOperation tco | store = tco.getInstruction(CrementStoreTag()) and From b185cc8b953d3e0cd3ca5610fd5b36d60723b9cb Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 14:09:34 +0200 Subject: [PATCH 3/7] C++: Factor out transparent conversions in their own predicate --- .../raw/internal/TranslatedExpr.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 705a9dcdd0b7..9e879283e3a7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -909,17 +909,17 @@ class TranslatedTransparentUnaryOperation extends TranslatedTransparentExpr { } } +private predicate isTransparentConversion(Conversion expr) { + expr instanceof ParenthesisExpr or + expr instanceof ReferenceDereferenceExpr or + expr instanceof ReferenceToExpr or + expr instanceof C11GenericExpr +} + class TranslatedTransparentConversion extends TranslatedTransparentExpr { override Conversion expr; - TranslatedTransparentConversion() { - ( - expr instanceof ParenthesisExpr or - expr instanceof ReferenceDereferenceExpr or - expr instanceof ReferenceToExpr or - expr instanceof C11GenericExpr - ) - } + TranslatedTransparentConversion() { isTransparentConversion(expr) } override TranslatedExpr getOperand() { result = getTranslatedExpr(expr.getExpr()) } } From 2908570ce915d5c6a339fb27838e235418cb56a3 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 14:10:34 +0200 Subject: [PATCH 4/7] C++: Do not consider expression results discardable when there is a conversion --- .../code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 9e879283e3a7..925b35cb2aa7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -4146,7 +4146,8 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) { private predicate exprImmediatelyDiscarded(Expr expr) { exists(ExprStmt s | s = expr.getParent() and - not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) + not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) and + not exists(Conversion c | c = expr.getConversion*() and not isTransparentConversion(c)) ) or exists(CommaExpr c | c.getLeftOperand() = expr) From d010b6eb016600099a5ea6b5ecac45c6153184b8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 14:28:17 +0200 Subject: [PATCH 5/7] C++: Update expected test results --- .../library-tests/dataflow/asExpr/test.cpp | 16 ++++++++-------- .../library-tests/ir/ir/aliased_ir.expected | 18 ++++++++++++------ .../test/library-tests/ir/ir/raw_ir.expected | 18 ++++++++++++------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp b/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp index 5f305ed21734..e0d37ccca09d 100644 --- a/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp @@ -42,16 +42,16 @@ void test_aggregate_literal() { void test_postfix_crement(int *p, int q) { p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr=p asIndirectExpr=p q++; // $ asExpr="... ++" asExpr=q - (p++); // $ numberOfNodes="... ++: 2" numberOfIndirectNodes="... ++: 2" asExpr="... ++" asIndirectExpr="... ++" MISSING: asExpr=p asIndirectExpr=p - (q++); // $ numberOfNodes="... ++: 2" asExpr="... ++" MISSING: asExpr=q - (void)(p++); // $ numberOfNodes="... ++: 2" asExpr="... ++" numberOfIndirectNodes="... ++: 2" asIndirectExpr="... ++" MISSING: asExpr=p asIndirectExpr=p - (void)(q++); // $ numberOfNodes="... ++: 2" asExpr="... ++" MISSING: asExpr=q - (void)p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr=p asIndirectExpr=p - (void)q++; // $ asExpr="... ++" asExpr=q + (p++); // $ numberOfNodes="... ++: 2" numberOfIndirectNodes="... ++: 2" asExpr="... ++" asIndirectExpr="... ++" + (q++); // $ numberOfNodes="... ++: 2" asExpr="... ++" + (void)(p++); // $ asExpr="p(... ++)" asIndirectExpr="p(*... ++)" + (void)(q++); // $ asExpr="q(... ++)" + (void)p++; // $ asExpr="p(... ++)" asIndirectExpr="p(*... ++)" + (void)q++; // $ asExpr="q(... ++)" int *p1 = p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)" int q1 = q++; // $ asExpr="... ++" asExpr="q(... ++)" - (int*)(p++); // $ numberOfIndirectNodes="... ++: 2" asExpr="... ++" asIndirectExpr="... ++" MISSING: asExpr="p(... ++)" asIndirectExpr="p(*... ++)" - (int)(q++); // $ asExpr="... ++" MISSING: asExpr="q(... ++)" + (int*)(p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)" + (int)(q++); // $ asExpr="... ++" asExpr="q(... ++)" int *p2 = (int*)(p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)" int q2 = (int)(q++); // $ asExpr="... ++" asExpr="q(... ++)" } diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 5b5e6a0585f8..c709ca76eb7c 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -20194,25 +20194,29 @@ ir.cpp: # 2733| r2733_3(int) = Constant[1] : # 2733| r2733_4(int *) = PointerAdd[4] : r2733_2, r2733_3 # 2733| m2733_5(int *) = Store[p] : &:r2733_1, r2733_4 -# 2733| v2733_6(void) = Convert : r2733_2 +# 2733| r2733_6(int *) = CopyValue : r2733_2 +# 2733| v2733_7(void) = Convert : r2733_6 # 2734| r2734_1(glval) = VariableAddress[q] : # 2734| r2734_2(int) = Load[q] : &:r2734_1, m2732_5 # 2734| r2734_3(int) = Constant[1] : # 2734| r2734_4(int) = Add : r2734_2, r2734_3 # 2734| m2734_5(int) = Store[q] : &:r2734_1, r2734_4 -# 2734| v2734_6(void) = Convert : r2734_2 +# 2734| r2734_6(int) = CopyValue : r2734_2 +# 2734| v2734_7(void) = Convert : r2734_6 # 2735| r2735_1(glval) = VariableAddress[p] : # 2735| r2735_2(int *) = Load[p] : &:r2735_1, m2733_5 # 2735| r2735_3(int) = Constant[1] : # 2735| r2735_4(int *) = PointerAdd[4] : r2735_2, r2735_3 # 2735| m2735_5(int *) = Store[p] : &:r2735_1, r2735_4 -# 2735| v2735_6(void) = Convert : r2735_2 +# 2735| r2735_6(int *) = CopyValue : r2735_2 +# 2735| v2735_7(void) = Convert : r2735_6 # 2736| r2736_1(glval) = VariableAddress[q] : # 2736| r2736_2(int) = Load[q] : &:r2736_1, m2734_5 # 2736| r2736_3(int) = Constant[1] : # 2736| r2736_4(int) = Add : r2736_2, r2736_3 # 2736| m2736_5(int) = Store[q] : &:r2736_1, r2736_4 -# 2736| v2736_6(void) = Convert : r2736_2 +# 2736| r2736_6(int) = CopyValue : r2736_2 +# 2736| v2736_7(void) = Convert : r2736_6 # 2737| r2737_1(glval) = VariableAddress[p1] : # 2737| r2737_2(glval) = VariableAddress[p] : # 2737| r2737_3(int *) = Load[p] : &:r2737_2, m2735_5 @@ -20234,13 +20238,15 @@ ir.cpp: # 2739| r2739_3(int) = Constant[1] : # 2739| r2739_4(int *) = PointerAdd[4] : r2739_2, r2739_3 # 2739| m2739_5(int *) = Store[p] : &:r2739_1, r2739_4 -# 2739| r2739_6(int *) = Convert : r2739_2 +# 2739| r2739_6(int *) = CopyValue : r2739_2 +# 2739| r2739_7(int *) = Convert : r2739_6 # 2740| r2740_1(glval) = VariableAddress[q] : # 2740| r2740_2(int) = Load[q] : &:r2740_1, m2738_6 # 2740| r2740_3(int) = Constant[1] : # 2740| r2740_4(int) = Add : r2740_2, r2740_3 # 2740| m2740_5(int) = Store[q] : &:r2740_1, r2740_4 -# 2740| r2740_6(int) = Convert : r2740_2 +# 2740| r2740_6(int) = CopyValue : r2740_2 +# 2740| r2740_7(int) = Convert : r2740_6 # 2741| r2741_1(glval) = VariableAddress[p2] : # 2741| r2741_2(glval) = VariableAddress[p] : # 2741| r2741_3(int *) = Load[p] : &:r2741_2, m2739_5 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 67e480d44ab2..6fb436b99396 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -18353,25 +18353,29 @@ ir.cpp: # 2733| r2733_3(int) = Constant[1] : # 2733| r2733_4(int *) = PointerAdd[4] : r2733_2, r2733_3 # 2733| mu2733_5(int *) = Store[p] : &:r2733_1, r2733_4 -# 2733| v2733_6(void) = Convert : r2733_2 +# 2733| r2733_6(int *) = CopyValue : r2733_2 +# 2733| v2733_7(void) = Convert : r2733_6 # 2734| r2734_1(glval) = VariableAddress[q] : # 2734| r2734_2(int) = Load[q] : &:r2734_1, ~m? # 2734| r2734_3(int) = Constant[1] : # 2734| r2734_4(int) = Add : r2734_2, r2734_3 # 2734| mu2734_5(int) = Store[q] : &:r2734_1, r2734_4 -# 2734| v2734_6(void) = Convert : r2734_2 +# 2734| r2734_6(int) = CopyValue : r2734_2 +# 2734| v2734_7(void) = Convert : r2734_6 # 2735| r2735_1(glval) = VariableAddress[p] : # 2735| r2735_2(int *) = Load[p] : &:r2735_1, ~m? # 2735| r2735_3(int) = Constant[1] : # 2735| r2735_4(int *) = PointerAdd[4] : r2735_2, r2735_3 # 2735| mu2735_5(int *) = Store[p] : &:r2735_1, r2735_4 -# 2735| v2735_6(void) = Convert : r2735_2 +# 2735| r2735_6(int *) = CopyValue : r2735_2 +# 2735| v2735_7(void) = Convert : r2735_6 # 2736| r2736_1(glval) = VariableAddress[q] : # 2736| r2736_2(int) = Load[q] : &:r2736_1, ~m? # 2736| r2736_3(int) = Constant[1] : # 2736| r2736_4(int) = Add : r2736_2, r2736_3 # 2736| mu2736_5(int) = Store[q] : &:r2736_1, r2736_4 -# 2736| v2736_6(void) = Convert : r2736_2 +# 2736| r2736_6(int) = CopyValue : r2736_2 +# 2736| v2736_7(void) = Convert : r2736_6 # 2737| r2737_1(glval) = VariableAddress[p1] : # 2737| r2737_2(glval) = VariableAddress[p] : # 2737| r2737_3(int *) = Load[p] : &:r2737_2, ~m? @@ -18393,13 +18397,15 @@ ir.cpp: # 2739| r2739_3(int) = Constant[1] : # 2739| r2739_4(int *) = PointerAdd[4] : r2739_2, r2739_3 # 2739| mu2739_5(int *) = Store[p] : &:r2739_1, r2739_4 -# 2739| r2739_6(int *) = Convert : r2739_2 +# 2739| r2739_6(int *) = CopyValue : r2739_2 +# 2739| r2739_7(int *) = Convert : r2739_6 # 2740| r2740_1(glval) = VariableAddress[q] : # 2740| r2740_2(int) = Load[q] : &:r2740_1, ~m? # 2740| r2740_3(int) = Constant[1] : # 2740| r2740_4(int) = Add : r2740_2, r2740_3 # 2740| mu2740_5(int) = Store[q] : &:r2740_1, r2740_4 -# 2740| r2740_6(int) = Convert : r2740_2 +# 2740| r2740_6(int) = CopyValue : r2740_2 +# 2740| r2740_7(int) = Convert : r2740_6 # 2741| r2741_1(glval) = VariableAddress[p2] : # 2741| r2741_2(glval) = VariableAddress[p] : # 2741| r2741_3(int *) = Load[p] : &:r2741_2, ~m? From 463ae4b1eb026012e3020e5775219a04d82decd1 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 23:13:37 +0200 Subject: [PATCH 6/7] C++: Address review comments --- .../cpp/ir/implementation/raw/internal/TranslatedExpr.qll | 2 +- cpp/ql/test/library-tests/dataflow/asExpr/test.cpp | 4 ++-- cpp/ql/test/library-tests/ir/ir/aliased_ir.expected | 2 ++ cpp/ql/test/library-tests/ir/ir/raw_ir.expected | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 925b35cb2aa7..332413042830 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -4147,7 +4147,7 @@ private predicate exprImmediatelyDiscarded(Expr expr) { exists(ExprStmt s | s = expr.getParent() and not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) and - not exists(Conversion c | c = expr.getConversion*() and not isTransparentConversion(c)) + not exists(expr.getConversion()) ) or exists(CommaExpr c | c.getLeftOperand() = expr) diff --git a/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp b/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp index e0d37ccca09d..8df12588fa59 100644 --- a/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/asExpr/test.cpp @@ -42,8 +42,8 @@ void test_aggregate_literal() { void test_postfix_crement(int *p, int q) { p++; // $ asExpr="... ++" asIndirectExpr="... ++" asExpr=p asIndirectExpr=p q++; // $ asExpr="... ++" asExpr=q - (p++); // $ numberOfNodes="... ++: 2" numberOfIndirectNodes="... ++: 2" asExpr="... ++" asIndirectExpr="... ++" - (q++); // $ numberOfNodes="... ++: 2" asExpr="... ++" + (p++); // $ asExpr="... ++" asIndirectExpr="... ++" asExpr="p(... ++)" asIndirectExpr="p(*... ++)" + (q++); // $ asExpr="... ++" asExpr="q(... ++)" (void)(p++); // $ asExpr="p(... ++)" asIndirectExpr="p(*... ++)" (void)(q++); // $ asExpr="q(... ++)" (void)p++; // $ asExpr="p(... ++)" asIndirectExpr="p(*... ++)" diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index c709ca76eb7c..4f1d1abb4ecf 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -20184,11 +20184,13 @@ ir.cpp: # 2731| r2731_3(int) = Constant[1] : # 2731| r2731_4(int *) = PointerAdd[4] : r2731_2, r2731_3 # 2731| m2731_5(int *) = Store[p] : &:r2731_1, r2731_4 +# 2731| r2731_6(int *) = CopyValue : r2731_2 # 2732| r2732_1(glval) = VariableAddress[q] : # 2732| r2732_2(int) = Load[q] : &:r2732_1, m2730_5 # 2732| r2732_3(int) = Constant[1] : # 2732| r2732_4(int) = Add : r2732_2, r2732_3 # 2732| m2732_5(int) = Store[q] : &:r2732_1, r2732_4 +# 2732| r2732_6(int) = CopyValue : r2732_2 # 2733| r2733_1(glval) = VariableAddress[p] : # 2733| r2733_2(int *) = Load[p] : &:r2733_1, m2731_5 # 2733| r2733_3(int) = Constant[1] : diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 6fb436b99396..937695c13ae5 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -18343,11 +18343,13 @@ ir.cpp: # 2731| r2731_3(int) = Constant[1] : # 2731| r2731_4(int *) = PointerAdd[4] : r2731_2, r2731_3 # 2731| mu2731_5(int *) = Store[p] : &:r2731_1, r2731_4 +# 2731| r2731_6(int *) = CopyValue : r2731_2 # 2732| r2732_1(glval) = VariableAddress[q] : # 2732| r2732_2(int) = Load[q] : &:r2732_1, ~m? # 2732| r2732_3(int) = Constant[1] : # 2732| r2732_4(int) = Add : r2732_2, r2732_3 # 2732| mu2732_5(int) = Store[q] : &:r2732_1, r2732_4 +# 2732| r2732_6(int) = CopyValue : r2732_2 # 2733| r2733_1(glval) = VariableAddress[p] : # 2733| r2733_2(int *) = Load[p] : &:r2733_1, ~m? # 2733| r2733_3(int) = Constant[1] : From d6d7c6d55f569aea83ca7e8b2629a5e30e9821f3 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 4 Jul 2025 23:22:46 +0200 Subject: [PATCH 7/7] Revert "C++: Factor out transparent conversions in their own predicate" This reverts commit b185cc8b953d3e0cd3ca5610fd5b36d60723b9cb. --- .../raw/internal/TranslatedExpr.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 332413042830..dea86499e7ca 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -909,17 +909,17 @@ class TranslatedTransparentUnaryOperation extends TranslatedTransparentExpr { } } -private predicate isTransparentConversion(Conversion expr) { - expr instanceof ParenthesisExpr or - expr instanceof ReferenceDereferenceExpr or - expr instanceof ReferenceToExpr or - expr instanceof C11GenericExpr -} - class TranslatedTransparentConversion extends TranslatedTransparentExpr { override Conversion expr; - TranslatedTransparentConversion() { isTransparentConversion(expr) } + TranslatedTransparentConversion() { + ( + expr instanceof ParenthesisExpr or + expr instanceof ReferenceDereferenceExpr or + expr instanceof ReferenceToExpr or + expr instanceof C11GenericExpr + ) + } override TranslatedExpr getOperand() { result = getTranslatedExpr(expr.getExpr()) } }