From 2ee82d07332eeebf026fc8de14a07c9dfe72c478 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 9 Jan 2026 19:22:37 +0000 Subject: [PATCH 1/6] C++: Add tests for assertions in release builds. --- .../library-tests/ir/ir/PrintAST.expected | 396 ++++++++++++++++++ .../library-tests/ir/ir/aliased_ir.expected | 147 +++++++ cpp/ql/test/library-tests/ir/ir/ir.cpp | 43 ++ .../test/library-tests/ir/ir/raw_ir.expected | 142 +++++++ 4 files changed, 728 insertions(+) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index e6f88ceb7789..7a15fdfc1c08 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -25131,6 +25131,402 @@ ir.cpp: # 2823| Type = [ArrayType] int[] # 2823| ValueCategory = lvalue # 2824| getStmt(5): [ReturnStmt] return ... +# 2830| [TopLevelFunction] void test_assert_simple(int, int, unsigned int, int) +# 2830| : +# 2830| getParameter(0): [Parameter] x +# 2830| Type = [IntType] int +# 2830| getParameter(1): [Parameter] y +# 2830| Type = [IntType] int +# 2830| getParameter(2): [Parameter] u +# 2830| Type = [IntType] unsigned int +# 2830| getParameter(3): [Parameter] shadowed +# 2830| Type = [IntType] int +# 2830| getEntryPoint(): [BlockStmt] { ... } +# 2831| getStmt(0): [ExprStmt] ExprStmt +# 2831| getExpr(): [Literal] 0 +# 2831| Type = [IntType] int +# 2831| Value = [Literal] 0 +# 2831| ValueCategory = prvalue +# 2831| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2831| Type = [VoidType] void +# 2831| ValueCategory = prvalue +# 2831| getExpr(): [CStyleCast] (void)... +# 2831| Conversion = [VoidConversion] conversion to void +# 2831| Type = [VoidType] void +# 2831| ValueCategory = prvalue +# 2832| getStmt(1): [ExprStmt] ExprStmt +# 2832| getExpr(): [Literal] 0 +# 2832| Type = [IntType] int +# 2832| Value = [Literal] 0 +# 2832| ValueCategory = prvalue +# 2832| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2832| Type = [VoidType] void +# 2832| ValueCategory = prvalue +# 2832| getExpr(): [CStyleCast] (void)... +# 2832| Conversion = [VoidConversion] conversion to void +# 2832| Type = [VoidType] void +# 2832| ValueCategory = prvalue +# 2833| getStmt(2): [ExprStmt] ExprStmt +# 2833| getExpr(): [Literal] 0 +# 2833| Type = [IntType] int +# 2833| Value = [Literal] 0 +# 2833| ValueCategory = prvalue +# 2833| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2833| Type = [VoidType] void +# 2833| ValueCategory = prvalue +# 2833| getExpr(): [CStyleCast] (void)... +# 2833| Conversion = [VoidConversion] conversion to void +# 2833| Type = [VoidType] void +# 2833| ValueCategory = prvalue +# 2835| getStmt(3): [EmptyStmt] ; +# 2837| getStmt(4): [ExprStmt] ExprStmt +# 2837| getExpr(): [Literal] 0 +# 2837| Type = [IntType] int +# 2837| Value = [Literal] 0 +# 2837| ValueCategory = prvalue +# 2837| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2837| Type = [VoidType] void +# 2837| ValueCategory = prvalue +# 2837| getExpr(): [CStyleCast] (void)... +# 2837| Conversion = [VoidConversion] conversion to void +# 2837| Type = [VoidType] void +# 2837| ValueCategory = prvalue +# 2839| getStmt(5): [BlockStmt] { ... } +# 2840| getStmt(0): [DeclStmt] declaration +# 2840| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed +# 2840| Type = [IntType] int +# 2840| getVariable().getInitializer(): [Initializer] initializer for shadowed +# 2840| getExpr(): [VariableAccess] x +# 2840| Type = [IntType] int +# 2840| ValueCategory = prvalue(load) +# 2841| getStmt(1): [ExprStmt] ExprStmt +# 2841| getExpr(): [Literal] 0 +# 2841| Type = [IntType] int +# 2841| Value = [Literal] 0 +# 2841| ValueCategory = prvalue +# 2841| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2841| Type = [VoidType] void +# 2841| ValueCategory = prvalue +# 2841| getExpr(): [CStyleCast] (void)... +# 2841| Conversion = [VoidConversion] conversion to void +# 2841| Type = [VoidType] void +# 2841| ValueCategory = prvalue +# 2843| getStmt(6): [ReturnStmt] return ... +# 2846| [TemplateFunction,TopLevelFunction] void test_assert_in_template(T, int, unsigned int) +# 2846| : +# 2846| getParameter(0): [Parameter] x +# 2846| Type = [TypeTemplateParameter] T +# 2846| getParameter(1): [Parameter] y +# 2846| Type = [IntType] int +# 2846| getParameter(2): [Parameter] u +# 2846| Type = [IntType] unsigned int +# 2846| getEntryPoint(): [BlockStmt] { ... } +# 2847| getStmt(0): [ExprStmt] ExprStmt +# 2847| getExpr(): [Literal] 0 +# 2847| Type = [IntType] int +# 2847| Value = [Literal] 0 +# 2847| ValueCategory = prvalue +# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2847| Type = [VoidType] void +# 2847| ValueCategory = prvalue +# 2847| getExpr(): [CStyleCast] (void)... +# 2847| Conversion = [VoidConversion] conversion to void +# 2847| Type = [VoidType] void +# 2847| ValueCategory = prvalue +# 2848| getStmt(1): [ExprStmt] ExprStmt +# 2848| getExpr(): [Literal] 0 +# 2848| Type = [IntType] int +# 2848| Value = [Literal] 0 +# 2848| ValueCategory = prvalue +# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2848| Type = [VoidType] void +# 2848| ValueCategory = prvalue +# 2848| getExpr(): [CStyleCast] (void)... +# 2848| Conversion = [VoidConversion] conversion to void +# 2848| Type = [VoidType] void +# 2848| ValueCategory = prvalue +# 2849| getStmt(2): [ExprStmt] ExprStmt +# 2849| getExpr(): [Literal] 0 +# 2849| Type = [IntType] int +# 2849| Value = [Literal] 0 +# 2849| ValueCategory = prvalue +# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2849| Type = [VoidType] void +# 2849| ValueCategory = prvalue +# 2849| getExpr(): [CStyleCast] (void)... +# 2849| Conversion = [VoidConversion] conversion to void +# 2849| Type = [VoidType] void +# 2849| ValueCategory = prvalue +# 2851| getStmt(3): [EmptyStmt] ; +# 2853| getStmt(4): [ExprStmt] ExprStmt +# 2853| getExpr(): [Literal] 0 +# 2853| Type = [IntType] int +# 2853| Value = [Literal] 0 +# 2853| ValueCategory = prvalue +# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2853| Type = [VoidType] void +# 2853| ValueCategory = prvalue +# 2853| getExpr(): [CStyleCast] (void)... +# 2853| Conversion = [VoidConversion] conversion to void +# 2853| Type = [VoidType] void +# 2853| ValueCategory = prvalue +# 2855| getStmt(5): [BlockStmt] { ... } +# 2856| getStmt(0): [DeclStmt] declaration +# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed +# 2856| Type = [IntType] int +# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed +# 2856| getExpr(): [VariableAccess] x +# 2856| Type = [TypeTemplateParameter] T +# 2856| ValueCategory = lvalue +# 2856| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2856| Type = [IntType] int +# 2856| ValueCategory = prvalue +# 2857| getStmt(1): [ExprStmt] ExprStmt +# 2857| getExpr(): [Literal] 0 +# 2857| Type = [IntType] int +# 2857| Value = [Literal] 0 +# 2857| ValueCategory = prvalue +# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2857| Type = [VoidType] void +# 2857| ValueCategory = prvalue +# 2857| getExpr(): [CStyleCast] (void)... +# 2857| Conversion = [VoidConversion] conversion to void +# 2857| Type = [VoidType] void +# 2857| ValueCategory = prvalue +# 2859| getStmt(6): [ReturnStmt] return ... +# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template(int, int, unsigned int) +# 2846| : +# 2846| getParameter(0): [Parameter] x +# 2846| Type = [IntType] int +# 2846| getParameter(1): [Parameter] y +# 2846| Type = [IntType] int +# 2846| getParameter(2): [Parameter] u +# 2846| Type = [IntType] unsigned int +# 2846| getEntryPoint(): [BlockStmt] { ... } +# 2847| getStmt(0): [ExprStmt] ExprStmt +# 2847| getExpr(): [Literal] 0 +# 2847| Type = [IntType] int +# 2847| Value = [Literal] 0 +# 2847| ValueCategory = prvalue +# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2847| Type = [VoidType] void +# 2847| ValueCategory = prvalue +# 2847| getExpr(): [CStyleCast] (void)... +# 2847| Conversion = [VoidConversion] conversion to void +# 2847| Type = [VoidType] void +# 2847| ValueCategory = prvalue +# 2848| getStmt(1): [ExprStmt] ExprStmt +# 2848| getExpr(): [Literal] 0 +# 2848| Type = [IntType] int +# 2848| Value = [Literal] 0 +# 2848| ValueCategory = prvalue +# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2848| Type = [VoidType] void +# 2848| ValueCategory = prvalue +# 2848| getExpr(): [CStyleCast] (void)... +# 2848| Conversion = [VoidConversion] conversion to void +# 2848| Type = [VoidType] void +# 2848| ValueCategory = prvalue +# 2849| getStmt(2): [ExprStmt] ExprStmt +# 2849| getExpr(): [Literal] 0 +# 2849| Type = [IntType] int +# 2849| Value = [Literal] 0 +# 2849| ValueCategory = prvalue +# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2849| Type = [VoidType] void +# 2849| ValueCategory = prvalue +# 2849| getExpr(): [CStyleCast] (void)... +# 2849| Conversion = [VoidConversion] conversion to void +# 2849| Type = [VoidType] void +# 2849| ValueCategory = prvalue +# 2851| getStmt(3): [EmptyStmt] ; +# 2853| getStmt(4): [ExprStmt] ExprStmt +# 2853| getExpr(): [Literal] 0 +# 2853| Type = [IntType] int +# 2853| Value = [Literal] 0 +# 2853| ValueCategory = prvalue +# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2853| Type = [VoidType] void +# 2853| ValueCategory = prvalue +# 2853| getExpr(): [CStyleCast] (void)... +# 2853| Conversion = [VoidConversion] conversion to void +# 2853| Type = [VoidType] void +# 2853| ValueCategory = prvalue +# 2855| getStmt(5): [BlockStmt] { ... } +# 2856| getStmt(0): [DeclStmt] declaration +# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed +# 2856| Type = [IntType] int +# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed +# 2856| getExpr(): [VariableAccess] x +# 2856| Type = [IntType] int +# 2856| ValueCategory = prvalue(load) +# 2857| getStmt(1): [ExprStmt] ExprStmt +# 2857| getExpr(): [Literal] 0 +# 2857| Type = [IntType] int +# 2857| Value = [Literal] 0 +# 2857| ValueCategory = prvalue +# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2857| Type = [VoidType] void +# 2857| ValueCategory = prvalue +# 2857| getExpr(): [CStyleCast] (void)... +# 2857| Conversion = [VoidConversion] conversion to void +# 2857| Type = [VoidType] void +# 2857| ValueCategory = prvalue +# 2859| getStmt(6): [ReturnStmt] return ... +# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template(short, int, unsigned int) +# 2846| : +# 2846| getParameter(0): [Parameter] x +# 2846| Type = [ShortType] short +# 2846| getParameter(1): [Parameter] y +# 2846| Type = [IntType] int +# 2846| getParameter(2): [Parameter] u +# 2846| Type = [IntType] unsigned int +# 2846| getEntryPoint(): [BlockStmt] { ... } +# 2847| getStmt(0): [ExprStmt] ExprStmt +# 2847| getExpr(): [Literal] 0 +# 2847| Type = [IntType] int +# 2847| Value = [Literal] 0 +# 2847| ValueCategory = prvalue +# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2847| Type = [VoidType] void +# 2847| ValueCategory = prvalue +# 2847| getExpr(): [CStyleCast] (void)... +# 2847| Conversion = [VoidConversion] conversion to void +# 2847| Type = [VoidType] void +# 2847| ValueCategory = prvalue +# 2848| getStmt(1): [ExprStmt] ExprStmt +# 2848| getExpr(): [Literal] 0 +# 2848| Type = [IntType] int +# 2848| Value = [Literal] 0 +# 2848| ValueCategory = prvalue +# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2848| Type = [VoidType] void +# 2848| ValueCategory = prvalue +# 2848| getExpr(): [CStyleCast] (void)... +# 2848| Conversion = [VoidConversion] conversion to void +# 2848| Type = [VoidType] void +# 2848| ValueCategory = prvalue +# 2849| getStmt(2): [ExprStmt] ExprStmt +# 2849| getExpr(): [Literal] 0 +# 2849| Type = [IntType] int +# 2849| Value = [Literal] 0 +# 2849| ValueCategory = prvalue +# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2849| Type = [VoidType] void +# 2849| ValueCategory = prvalue +# 2849| getExpr(): [CStyleCast] (void)... +# 2849| Conversion = [VoidConversion] conversion to void +# 2849| Type = [VoidType] void +# 2849| ValueCategory = prvalue +# 2851| getStmt(3): [EmptyStmt] ; +# 2853| getStmt(4): [ExprStmt] ExprStmt +# 2853| getExpr(): [Literal] 0 +# 2853| Type = [IntType] int +# 2853| Value = [Literal] 0 +# 2853| ValueCategory = prvalue +# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2853| Type = [VoidType] void +# 2853| ValueCategory = prvalue +# 2853| getExpr(): [CStyleCast] (void)... +# 2853| Conversion = [VoidConversion] conversion to void +# 2853| Type = [VoidType] void +# 2853| ValueCategory = prvalue +# 2855| getStmt(5): [BlockStmt] { ... } +# 2856| getStmt(0): [DeclStmt] declaration +# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed +# 2856| Type = [IntType] int +# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed +# 2856| getExpr(): [VariableAccess] x +# 2856| Type = [ShortType] short +# 2856| ValueCategory = prvalue(load) +# 2856| getExpr().getFullyConverted(): [CStyleCast] (int)... +# 2856| Conversion = [IntegralConversion] integral conversion +# 2856| Type = [IntType] int +# 2856| ValueCategory = prvalue +# 2857| getStmt(1): [ExprStmt] ExprStmt +# 2857| getExpr(): [Literal] 0 +# 2857| Type = [IntType] int +# 2857| Value = [Literal] 0 +# 2857| ValueCategory = prvalue +# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2857| Type = [VoidType] void +# 2857| ValueCategory = prvalue +# 2857| getExpr(): [CStyleCast] (void)... +# 2857| Conversion = [VoidConversion] conversion to void +# 2857| Type = [VoidType] void +# 2857| ValueCategory = prvalue +# 2859| getStmt(6): [ReturnStmt] return ... +# 2864| [TopLevelFunction] void complex_assertions(int, bool, int) +# 2864| : +# 2864| getParameter(0): [Parameter] x +# 2864| Type = [IntType] int +# 2864| getParameter(1): [Parameter] b +# 2864| Type = [BoolType] bool +# 2864| getParameter(2): [Parameter] max +# 2864| Type = [IntType] int +# 2864| getEntryPoint(): [BlockStmt] { ... } +# 2865| getStmt(0): [DeclStmt] declaration +# 2865| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 2865| Type = [IntType] int +# 2865| getVariable().getInitializer(): [Initializer] initializer for y +# 2865| getExpr(): [CommaExpr] ... , ... +# 2865| Type = [IntType] int +# 2865| ValueCategory = prvalue(load) +# 2865| getLeftOperand(): [Literal] 0 +# 2865| Type = [IntType] int +# 2865| Value = [Literal] 0 +# 2865| ValueCategory = prvalue +# 2865| getRightOperand(): [VariableAccess] x +# 2865| Type = [IntType] int +# 2865| ValueCategory = prvalue(load) +# 2865| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2865| Type = [VoidType] void +# 2865| ValueCategory = prvalue +# 2865| getExpr(): [CStyleCast] (void)... +# 2865| Conversion = [VoidConversion] conversion to void +# 2865| Type = [VoidType] void +# 2865| ValueCategory = prvalue +# 2865| getExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 2865| Type = [IntType] int +# 2865| ValueCategory = prvalue(load) +# 2866| getStmt(1): [DeclStmt] declaration +# 2866| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z +# 2866| Type = [IntType] int +# 2866| getVariable().getInitializer(): [Initializer] initializer for z +# 2866| getExpr(): [ConditionalExpr] ... ? ... : ... +# 2866| Type = [IntType] int +# 2866| ValueCategory = prvalue +# 2866| getCondition(): [VariableAccess] b +# 2866| Type = [BoolType] bool +# 2866| ValueCategory = prvalue(load) +# 2866| getThen(): [CommaExpr] ... , ... +# 2866| Type = [IntType] int +# 2866| Value = [CommaExpr] 0 +# 2866| ValueCategory = prvalue +# 2866| getLeftOperand(): [Literal] 0 +# 2866| Type = [IntType] int +# 2866| Value = [Literal] 0 +# 2866| ValueCategory = prvalue +# 2866| getRightOperand(): [Literal] 0 +# 2866| Type = [IntType] int +# 2866| Value = [Literal] 0 +# 2866| ValueCategory = prvalue +# 2866| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...) +# 2866| Type = [VoidType] void +# 2866| ValueCategory = prvalue +# 2866| getExpr(): [CStyleCast] (void)... +# 2866| Conversion = [VoidConversion] conversion to void +# 2866| Type = [VoidType] void +# 2866| ValueCategory = prvalue +# 2866| getElse(): [Literal] 1 +# 2866| Type = [IntType] int +# 2866| Value = [Literal] 1 +# 2866| ValueCategory = prvalue +# 2866| getThen().getFullyConverted(): [ParenthesisExpr] (...) +# 2866| Type = [IntType] int +# 2866| Value = [ParenthesisExpr] 0 +# 2866| ValueCategory = prvalue +# 2867| getStmt(2): [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 94daf808a722..648d05113e96 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -20741,6 +20741,153 @@ ir.cpp: # 2821| v2821_10(void) = AliasedUse : m2821_3 # 2821| v2821_11(void) = ExitFunction : +# 2830| void test_assert_simple(int, int, unsigned int, int) +# 2830| Block 0 +# 2830| v2830_1(void) = EnterFunction : +# 2830| m2830_2(unknown) = AliasedDefinition : +# 2830| m2830_3(unknown) = InitializeNonLocal : +# 2830| m2830_4(unknown) = Chi : total:m2830_2, partial:m2830_3 +# 2830| r2830_5(glval) = VariableAddress[x] : +# 2830| m2830_6(int) = InitializeParameter[x] : &:r2830_5 +# 2830| r2830_7(glval) = VariableAddress[y] : +# 2830| m2830_8(int) = InitializeParameter[y] : &:r2830_7 +# 2830| r2830_9(glval) = VariableAddress[u] : +# 2830| m2830_10(unsigned int) = InitializeParameter[u] : &:r2830_9 +# 2830| r2830_11(glval) = VariableAddress[shadowed] : +# 2830| m2830_12(int) = InitializeParameter[shadowed] : &:r2830_11 +# 2831| r2831_1(int) = Constant[0] : +# 2831| v2831_2(void) = Convert : r2831_1 +# 2832| r2832_1(int) = Constant[0] : +# 2832| v2832_2(void) = Convert : r2832_1 +# 2833| r2833_1(int) = Constant[0] : +# 2833| v2833_2(void) = Convert : r2833_1 +# 2835| v2835_1(void) = NoOp : +# 2837| r2837_1(int) = Constant[0] : +# 2837| v2837_2(void) = Convert : r2837_1 +# 2840| r2840_1(glval) = VariableAddress[shadowed] : +# 2840| r2840_2(glval) = VariableAddress[x] : +# 2840| r2840_3(int) = Load[x] : &:r2840_2, m2830_6 +# 2840| m2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3 +# 2841| r2841_1(int) = Constant[0] : +# 2841| v2841_2(void) = Convert : r2841_1 +# 2843| v2843_1(void) = NoOp : +# 2830| v2830_13(void) = ReturnVoid : +# 2830| v2830_14(void) = AliasedUse : m2830_3 +# 2830| v2830_15(void) = ExitFunction : + +# 2846| void test_assert_in_template(int, int, unsigned int) +# 2846| Block 0 +# 2846| v2846_1(void) = EnterFunction : +# 2846| m2846_2(unknown) = AliasedDefinition : +# 2846| m2846_3(unknown) = InitializeNonLocal : +# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3 +# 2846| r2846_5(glval) = VariableAddress[x] : +# 2846| m2846_6(int) = InitializeParameter[x] : &:r2846_5 +# 2846| r2846_7(glval) = VariableAddress[y] : +# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7 +# 2846| r2846_9(glval) = VariableAddress[u] : +# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9 +# 2847| r2847_1(int) = Constant[0] : +# 2847| v2847_2(void) = Convert : r2847_1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| v2848_2(void) = Convert : r2848_1 +# 2849| r2849_1(int) = Constant[0] : +# 2849| v2849_2(void) = Convert : r2849_1 +# 2851| v2851_1(void) = NoOp : +# 2853| r2853_1(int) = Constant[0] : +# 2853| v2853_2(void) = Convert : r2853_1 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(int) = Load[x] : &:r2856_2, m2846_6 +# 2856| m2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3 +# 2857| r2857_1(int) = Constant[0] : +# 2857| v2857_2(void) = Convert : r2857_1 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_11(void) = ReturnVoid : +# 2846| v2846_12(void) = AliasedUse : m2846_3 +# 2846| v2846_13(void) = ExitFunction : + +# 2846| void test_assert_in_template(short, int, unsigned int) +# 2846| Block 0 +# 2846| v2846_1(void) = EnterFunction : +# 2846| m2846_2(unknown) = AliasedDefinition : +# 2846| m2846_3(unknown) = InitializeNonLocal : +# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3 +# 2846| r2846_5(glval) = VariableAddress[x] : +# 2846| m2846_6(short) = InitializeParameter[x] : &:r2846_5 +# 2846| r2846_7(glval) = VariableAddress[y] : +# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7 +# 2846| r2846_9(glval) = VariableAddress[u] : +# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9 +# 2847| r2847_1(int) = Constant[0] : +# 2847| v2847_2(void) = Convert : r2847_1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| v2848_2(void) = Convert : r2848_1 +# 2849| r2849_1(int) = Constant[0] : +# 2849| v2849_2(void) = Convert : r2849_1 +# 2851| v2851_1(void) = NoOp : +# 2853| r2853_1(int) = Constant[0] : +# 2853| v2853_2(void) = Convert : r2853_1 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(short) = Load[x] : &:r2856_2, m2846_6 +# 2856| r2856_4(int) = Convert : r2856_3 +# 2856| m2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4 +# 2857| r2857_1(int) = Constant[0] : +# 2857| v2857_2(void) = Convert : r2857_1 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_11(void) = ReturnVoid : +# 2846| v2846_12(void) = AliasedUse : m2846_3 +# 2846| v2846_13(void) = ExitFunction : + +# 2864| void complex_assertions(int, bool, int) +# 2864| Block 0 +# 2864| v2864_1(void) = EnterFunction : +# 2864| m2864_2(unknown) = AliasedDefinition : +# 2864| m2864_3(unknown) = InitializeNonLocal : +# 2864| m2864_4(unknown) = Chi : total:m2864_2, partial:m2864_3 +# 2864| r2864_5(glval) = VariableAddress[x] : +# 2864| m2864_6(int) = InitializeParameter[x] : &:r2864_5 +# 2864| r2864_7(glval) = VariableAddress[b] : +# 2864| m2864_8(bool) = InitializeParameter[b] : &:r2864_7 +# 2864| r2864_9(glval) = VariableAddress[max] : +# 2864| m2864_10(int) = InitializeParameter[max] : &:r2864_9 +# 2865| r2865_1(glval) = VariableAddress[y] : +# 2865| r2865_2(int) = Constant[0] : +# 2865| v2865_3(void) = Convert : r2865_2 +# 2865| r2865_4(glval) = VariableAddress[x] : +# 2865| r2865_5(int) = Load[x] : &:r2865_4, m2864_6 +# 2865| r2865_6(int) = CopyValue : r2865_5 +# 2865| m2865_7(int) = Store[y] : &:r2865_1, r2865_6 +# 2866| r2866_1(glval) = VariableAddress[z] : +# 2866| r2866_2(glval) = VariableAddress[b] : +# 2866| r2866_3(bool) = Load[b] : &:r2866_2, m2864_8 +# 2866| v2866_4(void) = ConditionalBranch : r2866_3 +#-----| False -> Block 3 +#-----| True -> Block 2 + +# 2866| Block 1 +# 2866| m2866_5(int) = Phi : from 2:m2866_11, from 3:m2866_14 +# 2866| r2866_6(glval) = VariableAddress[#temp2866:13] : +# 2866| r2866_7(int) = Load[#temp2866:13] : &:r2866_6, m2866_5 +# 2866| m2866_8(int) = Store[z] : &:r2866_1, r2866_7 +# 2867| v2867_1(void) = NoOp : +# 2864| v2864_11(void) = ReturnVoid : +# 2864| v2864_12(void) = AliasedUse : m2864_3 +# 2864| v2864_13(void) = ExitFunction : + +# 2866| Block 2 +# 2866| r2866_9(int) = Constant[0] : +# 2866| r2866_10(glval) = VariableAddress[#temp2866:13] : +# 2866| m2866_11(int) = Store[#temp2866:13] : &:r2866_10, r2866_9 +#-----| Goto -> Block 1 + +# 2866| Block 3 +# 2866| r2866_12(int) = Constant[1] : +# 2866| r2866_13(glval) = VariableAddress[#temp2866:13] : +# 2866| m2866_14(int) = Store[#temp2866:13] : &:r2866_13, r2866_12 +#-----| Goto -> Block 1 + 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 99876f7e9a47..1e889bda6a14 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2823,4 +2823,47 @@ void vla_sizeof_test5(int len1, size_t len2) { size_t z = sizeof((*&tmp1)[1]); } +// Common definitions for assertions in release builds +#define assert(x) ((void)0) +#define __analysis_assume(x) + +void test_assert_simple(int x, int y, unsigned u, int shadowed) { + assert(x > 0); + assert(0 < x); + assert(x < y); + + __analysis_assume(x != 2); + + assert(u < x); + + { + int shadowed = x; + assert(shadowed > 0); + } +} + +template +void test_assert_in_template(T x, int y, unsigned u) { + assert(x > 0); + assert(0 < x); + assert(x < y); + + __analysis_assume(x != 2); + + assert(u < x); + + { + int shadowed = x; + assert(shadowed > 0); + } +} + +template void test_assert_in_template(int, int, unsigned); +template void test_assert_in_template(short, int, unsigned); + +void complex_assertions(int x, bool b, int max) { + int y = (assert(x > 0), x); + int z = b ? (assert(x != 0), 0) : 1; +} + // 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 94e18abb9dfa..6b5c5a4f813e 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -18880,6 +18880,148 @@ ir.cpp: # 2821| v2821_9(void) = AliasedUse : ~m? # 2821| v2821_10(void) = ExitFunction : +# 2830| void test_assert_simple(int, int, unsigned int, int) +# 2830| Block 0 +# 2830| v2830_1(void) = EnterFunction : +# 2830| mu2830_2(unknown) = AliasedDefinition : +# 2830| mu2830_3(unknown) = InitializeNonLocal : +# 2830| r2830_4(glval) = VariableAddress[x] : +# 2830| mu2830_5(int) = InitializeParameter[x] : &:r2830_4 +# 2830| r2830_6(glval) = VariableAddress[y] : +# 2830| mu2830_7(int) = InitializeParameter[y] : &:r2830_6 +# 2830| r2830_8(glval) = VariableAddress[u] : +# 2830| mu2830_9(unsigned int) = InitializeParameter[u] : &:r2830_8 +# 2830| r2830_10(glval) = VariableAddress[shadowed] : +# 2830| mu2830_11(int) = InitializeParameter[shadowed] : &:r2830_10 +# 2831| r2831_1(int) = Constant[0] : +# 2831| v2831_2(void) = Convert : r2831_1 +# 2832| r2832_1(int) = Constant[0] : +# 2832| v2832_2(void) = Convert : r2832_1 +# 2833| r2833_1(int) = Constant[0] : +# 2833| v2833_2(void) = Convert : r2833_1 +# 2835| v2835_1(void) = NoOp : +# 2837| r2837_1(int) = Constant[0] : +# 2837| v2837_2(void) = Convert : r2837_1 +# 2840| r2840_1(glval) = VariableAddress[shadowed] : +# 2840| r2840_2(glval) = VariableAddress[x] : +# 2840| r2840_3(int) = Load[x] : &:r2840_2, ~m? +# 2840| mu2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3 +# 2841| r2841_1(int) = Constant[0] : +# 2841| v2841_2(void) = Convert : r2841_1 +# 2843| v2843_1(void) = NoOp : +# 2830| v2830_12(void) = ReturnVoid : +# 2830| v2830_13(void) = AliasedUse : ~m? +# 2830| v2830_14(void) = ExitFunction : + +# 2846| void test_assert_in_template(int, int, unsigned int) +# 2846| Block 0 +# 2846| v2846_1(void) = EnterFunction : +# 2846| mu2846_2(unknown) = AliasedDefinition : +# 2846| mu2846_3(unknown) = InitializeNonLocal : +# 2846| r2846_4(glval) = VariableAddress[x] : +# 2846| mu2846_5(int) = InitializeParameter[x] : &:r2846_4 +# 2846| r2846_6(glval) = VariableAddress[y] : +# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6 +# 2846| r2846_8(glval) = VariableAddress[u] : +# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8 +# 2847| r2847_1(int) = Constant[0] : +# 2847| v2847_2(void) = Convert : r2847_1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| v2848_2(void) = Convert : r2848_1 +# 2849| r2849_1(int) = Constant[0] : +# 2849| v2849_2(void) = Convert : r2849_1 +# 2851| v2851_1(void) = NoOp : +# 2853| r2853_1(int) = Constant[0] : +# 2853| v2853_2(void) = Convert : r2853_1 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(int) = Load[x] : &:r2856_2, ~m? +# 2856| mu2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3 +# 2857| r2857_1(int) = Constant[0] : +# 2857| v2857_2(void) = Convert : r2857_1 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_10(void) = ReturnVoid : +# 2846| v2846_11(void) = AliasedUse : ~m? +# 2846| v2846_12(void) = ExitFunction : + +# 2846| void test_assert_in_template(short, int, unsigned int) +# 2846| Block 0 +# 2846| v2846_1(void) = EnterFunction : +# 2846| mu2846_2(unknown) = AliasedDefinition : +# 2846| mu2846_3(unknown) = InitializeNonLocal : +# 2846| r2846_4(glval) = VariableAddress[x] : +# 2846| mu2846_5(short) = InitializeParameter[x] : &:r2846_4 +# 2846| r2846_6(glval) = VariableAddress[y] : +# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6 +# 2846| r2846_8(glval) = VariableAddress[u] : +# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8 +# 2847| r2847_1(int) = Constant[0] : +# 2847| v2847_2(void) = Convert : r2847_1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| v2848_2(void) = Convert : r2848_1 +# 2849| r2849_1(int) = Constant[0] : +# 2849| v2849_2(void) = Convert : r2849_1 +# 2851| v2851_1(void) = NoOp : +# 2853| r2853_1(int) = Constant[0] : +# 2853| v2853_2(void) = Convert : r2853_1 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(short) = Load[x] : &:r2856_2, ~m? +# 2856| r2856_4(int) = Convert : r2856_3 +# 2856| mu2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4 +# 2857| r2857_1(int) = Constant[0] : +# 2857| v2857_2(void) = Convert : r2857_1 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_10(void) = ReturnVoid : +# 2846| v2846_11(void) = AliasedUse : ~m? +# 2846| v2846_12(void) = ExitFunction : + +# 2864| void complex_assertions(int, bool, int) +# 2864| Block 0 +# 2864| v2864_1(void) = EnterFunction : +# 2864| mu2864_2(unknown) = AliasedDefinition : +# 2864| mu2864_3(unknown) = InitializeNonLocal : +# 2864| r2864_4(glval) = VariableAddress[x] : +# 2864| mu2864_5(int) = InitializeParameter[x] : &:r2864_4 +# 2864| r2864_6(glval) = VariableAddress[b] : +# 2864| mu2864_7(bool) = InitializeParameter[b] : &:r2864_6 +# 2864| r2864_8(glval) = VariableAddress[max] : +# 2864| mu2864_9(int) = InitializeParameter[max] : &:r2864_8 +# 2865| r2865_1(glval) = VariableAddress[y] : +# 2865| r2865_2(int) = Constant[0] : +# 2865| v2865_3(void) = Convert : r2865_2 +# 2865| r2865_4(glval) = VariableAddress[x] : +# 2865| r2865_5(int) = Load[x] : &:r2865_4, ~m? +# 2865| r2865_6(int) = CopyValue : r2865_5 +# 2865| mu2865_7(int) = Store[y] : &:r2865_1, r2865_6 +# 2866| r2866_1(glval) = VariableAddress[z] : +# 2866| r2866_2(glval) = VariableAddress[b] : +# 2866| r2866_3(bool) = Load[b] : &:r2866_2, ~m? +# 2866| v2866_4(void) = ConditionalBranch : r2866_3 +#-----| False -> Block 3 +#-----| True -> Block 2 + +# 2866| Block 1 +# 2866| r2866_5(glval) = VariableAddress[#temp2866:13] : +# 2866| r2866_6(int) = Load[#temp2866:13] : &:r2866_5, ~m? +# 2866| mu2866_7(int) = Store[z] : &:r2866_1, r2866_6 +# 2867| v2867_1(void) = NoOp : +# 2864| v2864_10(void) = ReturnVoid : +# 2864| v2864_11(void) = AliasedUse : ~m? +# 2864| v2864_12(void) = ExitFunction : + +# 2866| Block 2 +# 2866| r2866_8(int) = Constant[0] : +# 2866| r2866_9(glval) = VariableAddress[#temp2866:13] : +# 2866| mu2866_10(int) = Store[#temp2866:13] : &:r2866_9, r2866_8 +#-----| Goto -> Block 1 + +# 2866| Block 3 +# 2866| r2866_11(int) = Constant[1] : +# 2866| r2866_12(glval) = VariableAddress[#temp2866:13] : +# 2866| mu2866_13(int) = Store[#temp2866:13] : &:r2866_12, r2866_11 +#-----| Goto -> Block 1 + ir23.cpp: # 1| bool consteval_1() # 1| Block 0 From 9718e003e9063871ce4131c6cf7137f80376c316 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 9 Jan 2026 19:23:19 +0000 Subject: [PATCH 2/6] C++: Add a few helper predicates. --- cpp/ql/lib/semmle/code/cpp/Element.qll | 5 +++++ cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 2 +- cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll | 7 +++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Element.qll b/cpp/ql/lib/semmle/code/cpp/Element.qll index b30503d2c94c..ffc0ede4daff 100644 --- a/cpp/ql/lib/semmle/code/cpp/Element.qll +++ b/cpp/ql/lib/semmle/code/cpp/Element.qll @@ -192,6 +192,11 @@ class Element extends ElementBase { */ predicate isAffectedByMacro() { affectedByMacro(this) } + /** Holds if this element is affected by the expansion of `mi`. */ + predicate isAffectedByMacro(MacroInvocation mi) { + affectedbymacroexpansion(underlyingElement(this), unresolveElement(mi)) + } + private Element getEnclosingElementPref() { enclosingfunction(underlyingElement(this), unresolveElement(result)) or result.(Function) = stmtEnclosingElement(this) or diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 60e2635f338a..851d987b1fd6 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -23,7 +23,7 @@ class Expr extends StmtParent, @expr { predicate hasChild(Expr e, int n) { e = this.getChild(n) } /** Gets the enclosing function of this expression, if any. */ - Function getEnclosingFunction() { result = exprEnclosingElement(this) } + override Function getEnclosingFunction() { result = exprEnclosingElement(this) } /** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */ BlockStmt getEnclosingBlock() { result = this.getEnclosingStmt().getEnclosingBlock() } diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll index bd3a54c61594..cd7504612444 100644 --- a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll @@ -20,7 +20,7 @@ class Stmt extends StmtParent, @stmt { predicate hasChild(Element e, int n) { this.getChild(n) = e } /** Gets the enclosing function of this statement, if any. */ - Function getEnclosingFunction() { result = stmtEnclosingElement(this) } + override Function getEnclosingFunction() { result = stmtEnclosingElement(this) } /** * Gets the nearest enclosing block of this statement in the source, if any. @@ -159,7 +159,10 @@ private class TStmtParent = @stmt or @expr; * * This is normally a statement, but may be a `StmtExpr`. */ -class StmtParent extends ControlFlowNode, TStmtParent { } +class StmtParent extends ControlFlowNode, TStmtParent { + /** Gets the enclosing function of this element, if any. */ + Function getEnclosingFunction() { none() } +} /** * A C/C++ 'expression' statement. From 945383590b82df35e68cc3233e8addb8ad87d6c6 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 9 Jan 2026 19:24:23 +0000 Subject: [PATCH 3/6] C++: Avoid generating IR for a few cases where we will be synthesizing assertions. --- .../raw/internal/TranslatedStmt.qll | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 9dccf7752aa8..82f1fd49b524 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -10,6 +10,7 @@ private import TranslatedElement private import TranslatedExpr private import TranslatedFunction private import TranslatedInitialization +private import TranslatedAssertion TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAst() = stmt } @@ -324,8 +325,16 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { class TranslatedEmptyStmt extends TranslatedStmt { TranslatedEmptyStmt() { - stmt instanceof EmptyStmt or - stmt instanceof LabelStmt or + // An assertion macro invocation can expand to + // an empty statement in release builds. In that case + // we synthedsize the check that would have occured. + // This is handled by `TranslatedAssertion.qll` and so + // we exclude these statements here. + not assertion(_, stmt) and + stmt instanceof EmptyStmt + or + stmt instanceof LabelStmt + or stmt instanceof SwitchCase } @@ -420,6 +429,15 @@ class TranslatedDeclStmt extends TranslatedStmt { class TranslatedExprStmt extends TranslatedStmt { override ExprStmt stmt; + TranslatedExprStmt() { + // An assertion macro invocation typically expand to the + // expression `((void)0)` in release builds. In that case + // we synthedsize the check that would have occured. + // This is handled by `TranslatedAssertion.qll` and so + // we exclude these statements here. + not assertion(_, stmt) + } + TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) } override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getExpr() } From 6915e81aa91031bfc8e5ff5881e4f0c45b3dde2d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 9 Jan 2026 19:30:12 +0000 Subject: [PATCH 4/6] C++: Generate IR for assertions in release builds. --- .../raw/internal/InstructionTag.qll | 14 +- .../raw/internal/TranslatedAssertion.qll | 375 ++++++++++++++++++ .../raw/internal/TranslatedElement.qll | 12 +- 3 files changed, 399 insertions(+), 2 deletions(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll index be3f680aa16d..e97e903f0025 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll @@ -104,7 +104,11 @@ newtype TInstructionTag = } or SizeofVlaDimensionTag(int index) { exists(VlaDeclStmt v | exists(v.getTransitiveVlaDimensionStmt(index))) - } + } or + AssertionVarAddressTag() or + AssertionVarLoadTag() or + AssertionOpTag() or + AssertionBranchTag() class InstructionTag extends TInstructionTag { final string toString() { result = getInstructionTagId(this) } @@ -296,4 +300,12 @@ string getInstructionTagId(TInstructionTag tag) { tag = CoAwaitBranchTag() and result = "CoAwaitBranch" or tag = BoolToIntConversionTag() and result = "BoolToIntConversion" + or + tag = AssertionVarAddressTag() and result = "AssertionVarAddress" + or + tag = AssertionVarLoadTag() and result = "AssertionVarLoad" + or + tag = AssertionOpTag() and result = "AssertionOp" + or + tag = AssertionBranchTag() and result = "AssertionBranch" } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll new file mode 100644 index 000000000000..bf058ab7f534 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll @@ -0,0 +1,375 @@ +private import cpp +private import semmle.code.cpp.ir.internal.IRUtilities +private import semmle.code.cpp.ir.implementation.internal.OperandTag +private import semmle.code.cpp.ir.internal.CppType +private import semmle.code.cpp.ir.internal.TempVariableTag +private import InstructionTag +private import TranslatedElement +private import TranslatedStmt +private import TranslatedFunction + +/** + * Holds if `s` is a statement that may be an expanded assertion in a + * release build. + */ +pragma[nomagic] +private predicate stmtCandidate(Stmt s) { + not s.isFromUninstantiatedTemplate(_) and + ( + // The expansion of `__analysis_assume(x != 0);` when `__analysis_assume` is + // empty is the empty statement. + s instanceof EmptyStmt + or + // The expansion of `assert(x != 0)` when `assert` is `((void)0)` is a zero literal + // with a void type. + exists(Expr e | + e = s.(ExprStmt).getExpr() and + e.getValue() = "0" and + e.getActualType() instanceof VoidType + ) + ) +} + +pragma[nomagic] +private predicate macroInvocationLocation(int startline, Function f, MacroInvocation mi) { + mi.getMacroName() = ["assert", "__analysis_assume"] and + mi.getLocation().hasLocationInfo(_, startline, _, _, _) and + f.getEntryPoint().isAffectedByMacro(mi) +} + +pragma[nomagic] +private predicate stmtParentLocation(int startline, Function f, StmtParent p) { + p.getEnclosingFunction() = f and + p.getLocation().hasLocationInfo(_, startline, _, _, _) +} + +/** + * Holds if `mi` is a macro invocation with a name that is known + * to correspond to an assertion macro, and the macro invocation + * is the only thing on the line. + */ +pragma[nomagic] +private predicate assertion0(MacroInvocation mi, Stmt s) { + stmtCandidate(s) and + s = + unique(StmtParent p, int startline, Function f | + macroInvocationLocation(startline, f, mi) and + stmtParentLocation(startline, f, p) and + // Also do not count the elements from the expanded macro. i.e., when checking + // if `assert(x)` is the only thing on the line we do not count the + // generated `((void)0)` expression. + not p = mi.getAnExpandedElement() + | + p + ) +} + +private Function getEnclosingFunctionForMacroInvocation(MacroInvocation mi) { + exists(Stmt s | + assertion0(mi, s) and + result = s.getEnclosingFunction() + ) +} + +/** + * Holds if `arg` has two components and the `i`'th component of the string + * `arg` is `s`, and the components are seperated by an operation with + * opcode `opcode`. + */ +bindingset[arg] +pragma[inline_late] +private predicate parseArgument(string arg, string s, int i, Opcode opcode) { + s = arg.regexpCapture("(.+)\\s<=\\s(.+)", i + 1) and + opcode instanceof Opcode::CompareLE + or + s = arg.regexpCapture("(.+)\\s>=\\s(.+)", i + 1) and + opcode instanceof Opcode::CompareGE + or + not arg.regexpMatch("(.+)\\s<=\\s(.+)") and + s = arg.regexpCapture("(.+)\\s<\\s(.+)", i + 1) and + opcode instanceof Opcode::CompareLT + or + not arg.regexpMatch("(.+)\\s>=\\s(.+)") and + s = arg.regexpCapture("(.+)\\s>\\s(.+)", i + 1) and + opcode instanceof Opcode::CompareGT + or + s = arg.regexpCapture("(.+)\\s!=\\s(.+)", i + 1) and + opcode instanceof Opcode::CompareNE + or + s = arg.regexpCapture("(.+)\\s==\\s(.+)", i + 1) and + opcode instanceof Opcode::CompareEQ +} + +/** Gets a local variable named `s` in `f`. */ +pragma[nomagic] +private LocalScopeVariable getAVariableWithNameInFunction(Function f, string s) { + result.getName() = s and + result.getFunction() = f +} + +/** Gets the field with name `s` in the declaring class of `mf`. */ +pragma[nomagic] +private Field getAFieldWithNameInClass(MemberFunction mf, string s) { + exists(Class c | + mf.getDeclaringType() = c and + c.getAField() = result and + result.hasName(s) + ) +} + +/** + * Holds if the `i`'th component of the macro invocation `mi` with opcode + * `opcode` is a reference to `var`. + */ +private predicate hasVarAccessMacroArgument(MacroInvocation mi, Variable var, int i, Opcode opcode) { + exists(string arg, string s, Function f | + arg = mi.getUnexpandedArgument(0) and + f = getEnclosingFunctionForMacroInvocation(mi) and + not exists(s.toInt()) and + parseArgument(arg, s, i, opcode) + | + var = unique( | | getAVariableWithNameInFunction(f, s)) + or + not exists(getAVariableWithNameInFunction(f, s)) and + var = getAFieldWithNameInClass(f, s) + ) +} + +/** + * Holds if the `i`'th component of the macro invocation `mi` with opcode + * `opcode` is a + * constant with the value `k`. + */ +private predicate hasConstMacroArgument(MacroInvocation mi, int k, int i, Opcode opcode) { + exists(string arg, string s | + assertion0(mi, _) and + arg = mi.getUnexpandedArgument(0) and + s.toInt() = k and + parseArgument(arg, s, i, opcode) + ) +} + +predicate hasAssertionOperand(MacroInvocation mi, int i) { + hasVarAccessMacroArgument(mi, _, i, _) + or + hasConstMacroArgument(mi, _, i, _) +} + +private predicate hasAssertionOpcode(MacroInvocation mi, Opcode opcode) { + hasVarAccessMacroArgument(mi, _, _, opcode) + or + hasConstMacroArgument(mi, _, _, opcode) +} + +/** + * Holds if `mi` is a macro invocation that is an assertion that should be generated + * in the control-flow graph at `s`. + */ +predicate assertion(MacroInvocation mi, Stmt s) { + assertion0(mi, s) and + hasAssertionOperand(mi, 0) and + hasAssertionOperand(mi, 1) +} + +/** The translation of an operand of an assertion. */ +abstract private class TranslatedAssertionOperand extends TranslatedElement, + TTranslatedAssertionOperand +{ + MacroInvocation mi; + int index; + + TranslatedAssertionOperand() { this = TTranslatedAssertionOperand(mi, index) } + + MacroInvocation getMacroInvocation() { result = mi } + + /** + * Gets the statement that is being replaced by the assertion that uses this + * operand. + */ + Stmt getStmt() { assertion(mi, result) } + + final override Locatable getAst() { result = this.getStmt() } + + final override TranslatedElement getChild(int id) { none() } + + final override Declaration getFunction() { result = this.getStmt().getEnclosingFunction() } + + /** Gets the instruction which holds the result of this operand. */ + abstract Instruction getResult(); + + final override string toString() { result = "Operand of assertion: " + mi } + + /** Gets the index of this operand (i.e., `0` or `1`). */ + final int getIndex() { result = index } +} + +/** An operand of an assertion that is a variable access. */ +private class TranslatedAssertionVarAccess extends TranslatedAssertionOperand { + TranslatedAssertionVarAccess() { hasVarAccessMacroArgument(mi, _, index, _) } + + Variable getVariable() { hasVarAccessMacroArgument(mi, result, index, _) } + + final override IRUserVariable getInstructionVariable(InstructionTag tag) { + tag = AssertionVarAddressTag() and + result.getVariable() = this.getVariable() + } + + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(AssertionVarAddressTag()) and kind instanceof GotoEdge + } + + final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { + tag = AssertionVarAddressTag() and + kind instanceof GotoEdge and + result = this.getInstruction(AssertionVarLoadTag()) + or + tag = AssertionVarLoadTag() and + result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind) + } + + final override Instruction getALastInstructionInternal() { + result = this.getInstruction(AssertionVarLoadTag()) + } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + exists(Variable v | v = this.getVariable() | + opcode instanceof Opcode::VariableAddress and + tag = AssertionVarAddressTag() and + resultType = getTypeForGLValue(v.getType()) + or + opcode instanceof Opcode::Load and + tag = AssertionVarLoadTag() and + resultType = getTypeForPRValue(v.getType()) + ) + } + + final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { + tag = AssertionVarLoadTag() and + operandTag instanceof AddressOperandTag and + result = this.getInstruction(AssertionVarAddressTag()) + } + + final override Instruction getResult() { result = this.getInstruction(AssertionVarLoadTag()) } +} + +/** An operand of an assertion that is a constant access. */ +private class TranslatedAssertionConst extends TranslatedAssertionOperand { + TranslatedAssertionConst() { hasConstMacroArgument(mi, _, index, _) } + + int getConst() { hasConstMacroArgument(mi, result, index, _) } + + final override string getInstructionConstantValue(InstructionTag tag) { + tag = OnlyInstructionTag() and + result = this.getConst().toString() + } + + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(OnlyInstructionTag()) and + kind instanceof GotoEdge + } + + final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { + tag = OnlyInstructionTag() and + result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind) + } + + final override Instruction getALastInstructionInternal() { + result = this.getInstruction(OnlyInstructionTag()) + } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + opcode instanceof Opcode::Constant and + tag = OnlyInstructionTag() and + resultType = getIntType() + } + + final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) } +} + +/** + * Gets the `TranslatedAssertionMacroInvocation` corresponding to the macro + * invocation `mi`. + */ +TranslatedAssertionMacroInvocation getTranslatedAssertionMacroInvocation(MacroInvocation mi) { + result.getMacroInvocation() = mi +} + +/** + * A synthesized assertion which would have otherwise been invisible because the + * database represents a release build where assertions are disabled. + */ +private class TranslatedAssertionMacroInvocation extends TranslatedStmt { + MacroInvocation mi; + + TranslatedAssertionMacroInvocation() { assertion(mi, stmt) } + + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getLeft().getFirstInstruction(kind) + } + + TranslatedAssertionOperand getLeft() { + result.getMacroInvocation() = mi and + result.getIndex() = 0 + } + + TranslatedAssertionOperand getRight() { + result.getMacroInvocation() = mi and + result.getIndex() = 1 + } + + final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { + tag = AssertionOpTag() and + kind instanceof GotoEdge and + result = this.getInstruction(AssertionBranchTag()) + or + tag = AssertionBranchTag() and + kind instanceof TrueEdge and + result = this.getParent().getChildSuccessor(this, _) + } + + final override TranslatedElement getChildInternal(int id) { + id = 0 and result = this.getLeft() + or + id = 1 and result = this.getRight() + } + + final override Instruction getALastInstructionInternal() { + result = this.getInstruction(AssertionBranchTag()) + } + + final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + tag = AssertionOpTag() and + resultType = getBoolType() and + hasAssertionOpcode(mi, opcode) + or + tag = AssertionBranchTag() and + resultType = getVoidType() and + opcode instanceof Opcode::ConditionalBranch + } + + final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { + child = this.getLeft() and + result = this.getRight().getFirstInstruction(kind) + or + child = this.getRight() and + kind instanceof GotoEdge and + result = this.getInstruction(AssertionOpTag()) + } + + final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { + tag = AssertionOpTag() and + ( + operandTag instanceof LeftOperandTag and + result = this.getLeft().getResult() + or + operandTag instanceof RightOperandTag and + result = this.getRight().getResult() + ) + or + tag = AssertionBranchTag() and + operandTag instanceof ConditionOperandTag and + result = this.getInstruction(AssertionOpTag()) + } + + MacroInvocation getMacroInvocation() { result = mi } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 330362f55603..9829388ef177 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -12,6 +12,7 @@ private import TranslatedFunction private import TranslatedStmt private import TranslatedExpr private import IRConstruction +private import TranslatedAssertion private import semmle.code.cpp.models.interfaces.SideEffect private import SideEffects @@ -138,6 +139,14 @@ private predicate ignoreExprAndDescendants(Expr expr) { // conditionally constructed (until we have a mechanism for calling these only when the // temporary's constructor was run) isConditionalTemporaryDestructorCall(expr) + or + // An assertion in a release build is often defined as `#define assert(x) ((void)0)`. + // We generate a synthetic assertion in release builds, and when we do that the + // expression `((void)0)` should not be translated. + exists(MacroInvocation mi | + assertion(mi, _) and + expr = mi.getExpr().getFullyConverted() + ) } /** @@ -909,7 +918,8 @@ newtype TTranslatedElement = } or // The side effect that initializes newly-allocated memory. TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or - TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } + TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or + TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) } /** * Gets the index of the first explicitly initialized element in `initList` From b08e3479b66d9faeea4853a9077498c93f0c5514 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 9 Jan 2026 19:49:43 +0000 Subject: [PATCH 5/6] C++: Accept test changes. --- .../library-tests/ir/ir/aliased_ir.expected | 267 +++++++++++++----- .../test/library-tests/ir/ir/raw_ir.expected | 263 ++++++++++++----- 2 files changed, 376 insertions(+), 154 deletions(-) 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 648d05113e96..4d703e1a262e 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -20755,90 +20755,201 @@ ir.cpp: # 2830| m2830_10(unsigned int) = InitializeParameter[u] : &:r2830_9 # 2830| r2830_11(glval) = VariableAddress[shadowed] : # 2830| m2830_12(int) = InitializeParameter[shadowed] : &:r2830_11 -# 2831| r2831_1(int) = Constant[0] : -# 2831| v2831_2(void) = Convert : r2831_1 -# 2832| r2832_1(int) = Constant[0] : -# 2832| v2832_2(void) = Convert : r2832_1 -# 2833| r2833_1(int) = Constant[0] : -# 2833| v2833_2(void) = Convert : r2833_1 -# 2835| v2835_1(void) = NoOp : -# 2837| r2837_1(int) = Constant[0] : -# 2837| v2837_2(void) = Convert : r2837_1 -# 2840| r2840_1(glval) = VariableAddress[shadowed] : -# 2840| r2840_2(glval) = VariableAddress[x] : -# 2840| r2840_3(int) = Load[x] : &:r2840_2, m2830_6 -# 2840| m2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3 -# 2841| r2841_1(int) = Constant[0] : -# 2841| v2841_2(void) = Convert : r2841_1 -# 2843| v2843_1(void) = NoOp : -# 2830| v2830_13(void) = ReturnVoid : -# 2830| v2830_14(void) = AliasedUse : m2830_3 -# 2830| v2830_15(void) = ExitFunction : +# 2831| r2831_1(glval) = VariableAddress[x] : +# 2831| r2831_2(int) = Load[x] : &:r2831_1, m2830_6 +# 2831| r2831_3(int) = Constant[0] : +# 2831| r2831_4(bool) = CompareGT : r2831_2, r2831_3 +# 2831| v2831_5(void) = ConditionalBranch : r2831_4 +#-----| True -> Block 1 + +# 2832| Block 1 +# 2832| r2832_1(int) = Constant[0] : +# 2832| r2832_2(glval) = VariableAddress[x] : +# 2832| r2832_3(int) = Load[x] : &:r2832_2, m2830_6 +# 2832| r2832_4(bool) = CompareLT : r2832_1, r2832_3 +# 2832| v2832_5(void) = ConditionalBranch : r2832_4 +#-----| True -> Block 2 + +# 2833| Block 2 +# 2833| r2833_1(glval) = VariableAddress[x] : +# 2833| r2833_2(int) = Load[x] : &:r2833_1, m2830_6 +# 2833| r2833_3(glval) = VariableAddress[y] : +# 2833| r2833_4(int) = Load[y] : &:r2833_3, m2830_8 +# 2833| r2833_5(bool) = CompareLT : r2833_2, r2833_4 +# 2833| v2833_6(void) = ConditionalBranch : r2833_5 +#-----| True -> Block 3 + +# 2835| Block 3 +# 2835| r2835_1(glval) = VariableAddress[x] : +# 2835| r2835_2(int) = Load[x] : &:r2835_1, m2830_6 +# 2835| r2835_3(int) = Constant[2] : +# 2835| r2835_4(bool) = CompareNE : r2835_2, r2835_3 +# 2835| v2835_5(void) = ConditionalBranch : r2835_4 +#-----| True -> Block 4 + +# 2837| Block 4 +# 2837| r2837_1(glval) = VariableAddress[u] : +# 2837| r2837_2(unsigned int) = Load[u] : &:r2837_1, m2830_10 +# 2837| r2837_3(glval) = VariableAddress[x] : +# 2837| r2837_4(int) = Load[x] : &:r2837_3, m2830_6 +# 2837| r2837_5(bool) = CompareLT : r2837_2, r2837_4 +# 2837| v2837_6(void) = ConditionalBranch : r2837_5 +#-----| True -> Block 5 + +# 2840| Block 5 +# 2840| r2840_1(glval) = VariableAddress[shadowed] : +# 2840| r2840_2(glval) = VariableAddress[x] : +# 2840| r2840_3(int) = Load[x] : &:r2840_2, m2830_6 +# 2840| m2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3 +# 2841| r2841_1(int) = Constant[0] : +# 2841| v2841_2(void) = Convert : r2841_1 +# 2843| v2843_1(void) = NoOp : +# 2830| v2830_13(void) = ReturnVoid : +# 2830| v2830_14(void) = AliasedUse : m2830_3 +# 2830| v2830_15(void) = ExitFunction : # 2846| void test_assert_in_template(int, int, unsigned int) # 2846| Block 0 -# 2846| v2846_1(void) = EnterFunction : -# 2846| m2846_2(unknown) = AliasedDefinition : -# 2846| m2846_3(unknown) = InitializeNonLocal : -# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3 -# 2846| r2846_5(glval) = VariableAddress[x] : -# 2846| m2846_6(int) = InitializeParameter[x] : &:r2846_5 -# 2846| r2846_7(glval) = VariableAddress[y] : -# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7 -# 2846| r2846_9(glval) = VariableAddress[u] : -# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9 -# 2847| r2847_1(int) = Constant[0] : -# 2847| v2847_2(void) = Convert : r2847_1 -# 2848| r2848_1(int) = Constant[0] : -# 2848| v2848_2(void) = Convert : r2848_1 -# 2849| r2849_1(int) = Constant[0] : -# 2849| v2849_2(void) = Convert : r2849_1 -# 2851| v2851_1(void) = NoOp : -# 2853| r2853_1(int) = Constant[0] : -# 2853| v2853_2(void) = Convert : r2853_1 -# 2856| r2856_1(glval) = VariableAddress[shadowed] : -# 2856| r2856_2(glval) = VariableAddress[x] : -# 2856| r2856_3(int) = Load[x] : &:r2856_2, m2846_6 -# 2856| m2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3 -# 2857| r2857_1(int) = Constant[0] : -# 2857| v2857_2(void) = Convert : r2857_1 -# 2859| v2859_1(void) = NoOp : -# 2846| v2846_11(void) = ReturnVoid : -# 2846| v2846_12(void) = AliasedUse : m2846_3 -# 2846| v2846_13(void) = ExitFunction : +# 2846| v2846_1(void) = EnterFunction : +# 2846| m2846_2(unknown) = AliasedDefinition : +# 2846| m2846_3(unknown) = InitializeNonLocal : +# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3 +# 2846| r2846_5(glval) = VariableAddress[x] : +# 2846| m2846_6(int) = InitializeParameter[x] : &:r2846_5 +# 2846| r2846_7(glval) = VariableAddress[y] : +# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7 +# 2846| r2846_9(glval) = VariableAddress[u] : +# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9 +# 2847| r2847_1(glval) = VariableAddress[x] : +# 2847| r2847_2(int) = Load[x] : &:r2847_1, m2846_6 +# 2847| r2847_3(int) = Constant[0] : +# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3 +# 2847| v2847_5(void) = ConditionalBranch : r2847_4 +#-----| True -> Block 1 + +# 2848| Block 1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| r2848_2(glval) = VariableAddress[x] : +# 2848| r2848_3(int) = Load[x] : &:r2848_2, m2846_6 +# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3 +# 2848| v2848_5(void) = ConditionalBranch : r2848_4 +#-----| True -> Block 2 + +# 2849| Block 2 +# 2849| r2849_1(glval) = VariableAddress[x] : +# 2849| r2849_2(int) = Load[x] : &:r2849_1, m2846_6 +# 2849| r2849_3(glval) = VariableAddress[y] : +# 2849| r2849_4(int) = Load[y] : &:r2849_3, m2846_8 +# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4 +# 2849| v2849_6(void) = ConditionalBranch : r2849_5 +#-----| True -> Block 3 + +# 2851| Block 3 +# 2851| r2851_1(glval) = VariableAddress[x] : +# 2851| r2851_2(int) = Load[x] : &:r2851_1, m2846_6 +# 2851| r2851_3(int) = Constant[2] : +# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3 +# 2851| v2851_5(void) = ConditionalBranch : r2851_4 +#-----| True -> Block 4 + +# 2853| Block 4 +# 2853| r2853_1(glval) = VariableAddress[u] : +# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10 +# 2853| r2853_3(glval) = VariableAddress[x] : +# 2853| r2853_4(int) = Load[x] : &:r2853_3, m2846_6 +# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4 +# 2853| v2853_6(void) = ConditionalBranch : r2853_5 +#-----| True -> Block 5 + +# 2856| Block 5 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(int) = Load[x] : &:r2856_2, m2846_6 +# 2856| m2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3 +# 2857| r2857_1(glval) = VariableAddress[shadowed] : +# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, m2856_4 +# 2857| r2857_3(int) = Constant[0] : +# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3 +# 2857| v2857_5(void) = ConditionalBranch : r2857_4 +#-----| True -> Block 6 + +# 2859| Block 6 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_11(void) = ReturnVoid : +# 2846| v2846_12(void) = AliasedUse : m2846_3 +# 2846| v2846_13(void) = ExitFunction : # 2846| void test_assert_in_template(short, int, unsigned int) # 2846| Block 0 -# 2846| v2846_1(void) = EnterFunction : -# 2846| m2846_2(unknown) = AliasedDefinition : -# 2846| m2846_3(unknown) = InitializeNonLocal : -# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3 -# 2846| r2846_5(glval) = VariableAddress[x] : -# 2846| m2846_6(short) = InitializeParameter[x] : &:r2846_5 -# 2846| r2846_7(glval) = VariableAddress[y] : -# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7 -# 2846| r2846_9(glval) = VariableAddress[u] : -# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9 -# 2847| r2847_1(int) = Constant[0] : -# 2847| v2847_2(void) = Convert : r2847_1 -# 2848| r2848_1(int) = Constant[0] : -# 2848| v2848_2(void) = Convert : r2848_1 -# 2849| r2849_1(int) = Constant[0] : -# 2849| v2849_2(void) = Convert : r2849_1 -# 2851| v2851_1(void) = NoOp : -# 2853| r2853_1(int) = Constant[0] : -# 2853| v2853_2(void) = Convert : r2853_1 -# 2856| r2856_1(glval) = VariableAddress[shadowed] : -# 2856| r2856_2(glval) = VariableAddress[x] : -# 2856| r2856_3(short) = Load[x] : &:r2856_2, m2846_6 -# 2856| r2856_4(int) = Convert : r2856_3 -# 2856| m2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4 -# 2857| r2857_1(int) = Constant[0] : -# 2857| v2857_2(void) = Convert : r2857_1 -# 2859| v2859_1(void) = NoOp : -# 2846| v2846_11(void) = ReturnVoid : -# 2846| v2846_12(void) = AliasedUse : m2846_3 -# 2846| v2846_13(void) = ExitFunction : +# 2846| v2846_1(void) = EnterFunction : +# 2846| m2846_2(unknown) = AliasedDefinition : +# 2846| m2846_3(unknown) = InitializeNonLocal : +# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3 +# 2846| r2846_5(glval) = VariableAddress[x] : +# 2846| m2846_6(short) = InitializeParameter[x] : &:r2846_5 +# 2846| r2846_7(glval) = VariableAddress[y] : +# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7 +# 2846| r2846_9(glval) = VariableAddress[u] : +# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9 +# 2847| r2847_1(glval) = VariableAddress[x] : +# 2847| r2847_2(short) = Load[x] : &:r2847_1, m2846_6 +# 2847| r2847_3(int) = Constant[0] : +# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3 +# 2847| v2847_5(void) = ConditionalBranch : r2847_4 +#-----| True -> Block 1 + +# 2848| Block 1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| r2848_2(glval) = VariableAddress[x] : +# 2848| r2848_3(short) = Load[x] : &:r2848_2, m2846_6 +# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3 +# 2848| v2848_5(void) = ConditionalBranch : r2848_4 +#-----| True -> Block 2 + +# 2849| Block 2 +# 2849| r2849_1(glval) = VariableAddress[x] : +# 2849| r2849_2(short) = Load[x] : &:r2849_1, m2846_6 +# 2849| r2849_3(glval) = VariableAddress[y] : +# 2849| r2849_4(int) = Load[y] : &:r2849_3, m2846_8 +# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4 +# 2849| v2849_6(void) = ConditionalBranch : r2849_5 +#-----| True -> Block 3 + +# 2851| Block 3 +# 2851| r2851_1(glval) = VariableAddress[x] : +# 2851| r2851_2(short) = Load[x] : &:r2851_1, m2846_6 +# 2851| r2851_3(int) = Constant[2] : +# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3 +# 2851| v2851_5(void) = ConditionalBranch : r2851_4 +#-----| True -> Block 4 + +# 2853| Block 4 +# 2853| r2853_1(glval) = VariableAddress[u] : +# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10 +# 2853| r2853_3(glval) = VariableAddress[x] : +# 2853| r2853_4(short) = Load[x] : &:r2853_3, m2846_6 +# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4 +# 2853| v2853_6(void) = ConditionalBranch : r2853_5 +#-----| True -> Block 5 + +# 2856| Block 5 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(short) = Load[x] : &:r2856_2, m2846_6 +# 2856| r2856_4(int) = Convert : r2856_3 +# 2856| m2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4 +# 2857| r2857_1(glval) = VariableAddress[shadowed] : +# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, m2856_5 +# 2857| r2857_3(int) = Constant[0] : +# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3 +# 2857| v2857_5(void) = ConditionalBranch : r2857_4 +#-----| True -> Block 6 + +# 2859| Block 6 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_11(void) = ReturnVoid : +# 2846| v2846_12(void) = AliasedUse : m2846_3 +# 2846| v2846_13(void) = ExitFunction : # 2864| void complex_assertions(int, bool, int) # 2864| Block 0 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 6b5c5a4f813e..938593e55b6c 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -18893,88 +18893,199 @@ ir.cpp: # 2830| mu2830_9(unsigned int) = InitializeParameter[u] : &:r2830_8 # 2830| r2830_10(glval) = VariableAddress[shadowed] : # 2830| mu2830_11(int) = InitializeParameter[shadowed] : &:r2830_10 -# 2831| r2831_1(int) = Constant[0] : -# 2831| v2831_2(void) = Convert : r2831_1 -# 2832| r2832_1(int) = Constant[0] : -# 2832| v2832_2(void) = Convert : r2832_1 -# 2833| r2833_1(int) = Constant[0] : -# 2833| v2833_2(void) = Convert : r2833_1 -# 2835| v2835_1(void) = NoOp : -# 2837| r2837_1(int) = Constant[0] : -# 2837| v2837_2(void) = Convert : r2837_1 -# 2840| r2840_1(glval) = VariableAddress[shadowed] : -# 2840| r2840_2(glval) = VariableAddress[x] : -# 2840| r2840_3(int) = Load[x] : &:r2840_2, ~m? -# 2840| mu2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3 -# 2841| r2841_1(int) = Constant[0] : -# 2841| v2841_2(void) = Convert : r2841_1 -# 2843| v2843_1(void) = NoOp : -# 2830| v2830_12(void) = ReturnVoid : -# 2830| v2830_13(void) = AliasedUse : ~m? -# 2830| v2830_14(void) = ExitFunction : +# 2831| r2831_1(glval) = VariableAddress[x] : +# 2831| r2831_2(int) = Load[x] : &:r2831_1, ~m? +# 2831| r2831_3(int) = Constant[0] : +# 2831| r2831_4(bool) = CompareGT : r2831_2, r2831_3 +# 2831| v2831_5(void) = ConditionalBranch : r2831_4 +#-----| True -> Block 1 + +# 2832| Block 1 +# 2832| r2832_1(int) = Constant[0] : +# 2832| r2832_2(glval) = VariableAddress[x] : +# 2832| r2832_3(int) = Load[x] : &:r2832_2, ~m? +# 2832| r2832_4(bool) = CompareLT : r2832_1, r2832_3 +# 2832| v2832_5(void) = ConditionalBranch : r2832_4 +#-----| True -> Block 2 + +# 2833| Block 2 +# 2833| r2833_1(glval) = VariableAddress[x] : +# 2833| r2833_2(int) = Load[x] : &:r2833_1, ~m? +# 2833| r2833_3(glval) = VariableAddress[y] : +# 2833| r2833_4(int) = Load[y] : &:r2833_3, ~m? +# 2833| r2833_5(bool) = CompareLT : r2833_2, r2833_4 +# 2833| v2833_6(void) = ConditionalBranch : r2833_5 +#-----| True -> Block 3 + +# 2835| Block 3 +# 2835| r2835_1(glval) = VariableAddress[x] : +# 2835| r2835_2(int) = Load[x] : &:r2835_1, ~m? +# 2835| r2835_3(int) = Constant[2] : +# 2835| r2835_4(bool) = CompareNE : r2835_2, r2835_3 +# 2835| v2835_5(void) = ConditionalBranch : r2835_4 +#-----| True -> Block 4 + +# 2837| Block 4 +# 2837| r2837_1(glval) = VariableAddress[u] : +# 2837| r2837_2(unsigned int) = Load[u] : &:r2837_1, ~m? +# 2837| r2837_3(glval) = VariableAddress[x] : +# 2837| r2837_4(int) = Load[x] : &:r2837_3, ~m? +# 2837| r2837_5(bool) = CompareLT : r2837_2, r2837_4 +# 2837| v2837_6(void) = ConditionalBranch : r2837_5 +#-----| True -> Block 5 + +# 2840| Block 5 +# 2840| r2840_1(glval) = VariableAddress[shadowed] : +# 2840| r2840_2(glval) = VariableAddress[x] : +# 2840| r2840_3(int) = Load[x] : &:r2840_2, ~m? +# 2840| mu2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3 +# 2841| r2841_1(int) = Constant[0] : +# 2841| v2841_2(void) = Convert : r2841_1 +# 2843| v2843_1(void) = NoOp : +# 2830| v2830_12(void) = ReturnVoid : +# 2830| v2830_13(void) = AliasedUse : ~m? +# 2830| v2830_14(void) = ExitFunction : # 2846| void test_assert_in_template(int, int, unsigned int) # 2846| Block 0 -# 2846| v2846_1(void) = EnterFunction : -# 2846| mu2846_2(unknown) = AliasedDefinition : -# 2846| mu2846_3(unknown) = InitializeNonLocal : -# 2846| r2846_4(glval) = VariableAddress[x] : -# 2846| mu2846_5(int) = InitializeParameter[x] : &:r2846_4 -# 2846| r2846_6(glval) = VariableAddress[y] : -# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6 -# 2846| r2846_8(glval) = VariableAddress[u] : -# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8 -# 2847| r2847_1(int) = Constant[0] : -# 2847| v2847_2(void) = Convert : r2847_1 -# 2848| r2848_1(int) = Constant[0] : -# 2848| v2848_2(void) = Convert : r2848_1 -# 2849| r2849_1(int) = Constant[0] : -# 2849| v2849_2(void) = Convert : r2849_1 -# 2851| v2851_1(void) = NoOp : -# 2853| r2853_1(int) = Constant[0] : -# 2853| v2853_2(void) = Convert : r2853_1 -# 2856| r2856_1(glval) = VariableAddress[shadowed] : -# 2856| r2856_2(glval) = VariableAddress[x] : -# 2856| r2856_3(int) = Load[x] : &:r2856_2, ~m? -# 2856| mu2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3 -# 2857| r2857_1(int) = Constant[0] : -# 2857| v2857_2(void) = Convert : r2857_1 -# 2859| v2859_1(void) = NoOp : -# 2846| v2846_10(void) = ReturnVoid : -# 2846| v2846_11(void) = AliasedUse : ~m? -# 2846| v2846_12(void) = ExitFunction : +# 2846| v2846_1(void) = EnterFunction : +# 2846| mu2846_2(unknown) = AliasedDefinition : +# 2846| mu2846_3(unknown) = InitializeNonLocal : +# 2846| r2846_4(glval) = VariableAddress[x] : +# 2846| mu2846_5(int) = InitializeParameter[x] : &:r2846_4 +# 2846| r2846_6(glval) = VariableAddress[y] : +# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6 +# 2846| r2846_8(glval) = VariableAddress[u] : +# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8 +# 2847| r2847_1(glval) = VariableAddress[x] : +# 2847| r2847_2(int) = Load[x] : &:r2847_1, ~m? +# 2847| r2847_3(int) = Constant[0] : +# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3 +# 2847| v2847_5(void) = ConditionalBranch : r2847_4 +#-----| True -> Block 1 + +# 2848| Block 1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| r2848_2(glval) = VariableAddress[x] : +# 2848| r2848_3(int) = Load[x] : &:r2848_2, ~m? +# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3 +# 2848| v2848_5(void) = ConditionalBranch : r2848_4 +#-----| True -> Block 2 + +# 2849| Block 2 +# 2849| r2849_1(glval) = VariableAddress[x] : +# 2849| r2849_2(int) = Load[x] : &:r2849_1, ~m? +# 2849| r2849_3(glval) = VariableAddress[y] : +# 2849| r2849_4(int) = Load[y] : &:r2849_3, ~m? +# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4 +# 2849| v2849_6(void) = ConditionalBranch : r2849_5 +#-----| True -> Block 3 + +# 2851| Block 3 +# 2851| r2851_1(glval) = VariableAddress[x] : +# 2851| r2851_2(int) = Load[x] : &:r2851_1, ~m? +# 2851| r2851_3(int) = Constant[2] : +# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3 +# 2851| v2851_5(void) = ConditionalBranch : r2851_4 +#-----| True -> Block 4 + +# 2853| Block 4 +# 2853| r2853_1(glval) = VariableAddress[u] : +# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, ~m? +# 2853| r2853_3(glval) = VariableAddress[x] : +# 2853| r2853_4(int) = Load[x] : &:r2853_3, ~m? +# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4 +# 2853| v2853_6(void) = ConditionalBranch : r2853_5 +#-----| True -> Block 5 + +# 2856| Block 5 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(int) = Load[x] : &:r2856_2, ~m? +# 2856| mu2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3 +# 2857| r2857_1(glval) = VariableAddress[shadowed] : +# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, ~m? +# 2857| r2857_3(int) = Constant[0] : +# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3 +# 2857| v2857_5(void) = ConditionalBranch : r2857_4 +#-----| True -> Block 6 + +# 2859| Block 6 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_10(void) = ReturnVoid : +# 2846| v2846_11(void) = AliasedUse : ~m? +# 2846| v2846_12(void) = ExitFunction : # 2846| void test_assert_in_template(short, int, unsigned int) # 2846| Block 0 -# 2846| v2846_1(void) = EnterFunction : -# 2846| mu2846_2(unknown) = AliasedDefinition : -# 2846| mu2846_3(unknown) = InitializeNonLocal : -# 2846| r2846_4(glval) = VariableAddress[x] : -# 2846| mu2846_5(short) = InitializeParameter[x] : &:r2846_4 -# 2846| r2846_6(glval) = VariableAddress[y] : -# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6 -# 2846| r2846_8(glval) = VariableAddress[u] : -# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8 -# 2847| r2847_1(int) = Constant[0] : -# 2847| v2847_2(void) = Convert : r2847_1 -# 2848| r2848_1(int) = Constant[0] : -# 2848| v2848_2(void) = Convert : r2848_1 -# 2849| r2849_1(int) = Constant[0] : -# 2849| v2849_2(void) = Convert : r2849_1 -# 2851| v2851_1(void) = NoOp : -# 2853| r2853_1(int) = Constant[0] : -# 2853| v2853_2(void) = Convert : r2853_1 -# 2856| r2856_1(glval) = VariableAddress[shadowed] : -# 2856| r2856_2(glval) = VariableAddress[x] : -# 2856| r2856_3(short) = Load[x] : &:r2856_2, ~m? -# 2856| r2856_4(int) = Convert : r2856_3 -# 2856| mu2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4 -# 2857| r2857_1(int) = Constant[0] : -# 2857| v2857_2(void) = Convert : r2857_1 -# 2859| v2859_1(void) = NoOp : -# 2846| v2846_10(void) = ReturnVoid : -# 2846| v2846_11(void) = AliasedUse : ~m? -# 2846| v2846_12(void) = ExitFunction : +# 2846| v2846_1(void) = EnterFunction : +# 2846| mu2846_2(unknown) = AliasedDefinition : +# 2846| mu2846_3(unknown) = InitializeNonLocal : +# 2846| r2846_4(glval) = VariableAddress[x] : +# 2846| mu2846_5(short) = InitializeParameter[x] : &:r2846_4 +# 2846| r2846_6(glval) = VariableAddress[y] : +# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6 +# 2846| r2846_8(glval) = VariableAddress[u] : +# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8 +# 2847| r2847_1(glval) = VariableAddress[x] : +# 2847| r2847_2(short) = Load[x] : &:r2847_1, ~m? +# 2847| r2847_3(int) = Constant[0] : +# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3 +# 2847| v2847_5(void) = ConditionalBranch : r2847_4 +#-----| True -> Block 1 + +# 2848| Block 1 +# 2848| r2848_1(int) = Constant[0] : +# 2848| r2848_2(glval) = VariableAddress[x] : +# 2848| r2848_3(short) = Load[x] : &:r2848_2, ~m? +# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3 +# 2848| v2848_5(void) = ConditionalBranch : r2848_4 +#-----| True -> Block 2 + +# 2849| Block 2 +# 2849| r2849_1(glval) = VariableAddress[x] : +# 2849| r2849_2(short) = Load[x] : &:r2849_1, ~m? +# 2849| r2849_3(glval) = VariableAddress[y] : +# 2849| r2849_4(int) = Load[y] : &:r2849_3, ~m? +# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4 +# 2849| v2849_6(void) = ConditionalBranch : r2849_5 +#-----| True -> Block 3 + +# 2851| Block 3 +# 2851| r2851_1(glval) = VariableAddress[x] : +# 2851| r2851_2(short) = Load[x] : &:r2851_1, ~m? +# 2851| r2851_3(int) = Constant[2] : +# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3 +# 2851| v2851_5(void) = ConditionalBranch : r2851_4 +#-----| True -> Block 4 + +# 2853| Block 4 +# 2853| r2853_1(glval) = VariableAddress[u] : +# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, ~m? +# 2853| r2853_3(glval) = VariableAddress[x] : +# 2853| r2853_4(short) = Load[x] : &:r2853_3, ~m? +# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4 +# 2853| v2853_6(void) = ConditionalBranch : r2853_5 +#-----| True -> Block 5 + +# 2856| Block 5 +# 2856| r2856_1(glval) = VariableAddress[shadowed] : +# 2856| r2856_2(glval) = VariableAddress[x] : +# 2856| r2856_3(short) = Load[x] : &:r2856_2, ~m? +# 2856| r2856_4(int) = Convert : r2856_3 +# 2856| mu2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4 +# 2857| r2857_1(glval) = VariableAddress[shadowed] : +# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, ~m? +# 2857| r2857_3(int) = Constant[0] : +# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3 +# 2857| v2857_5(void) = ConditionalBranch : r2857_4 +#-----| True -> Block 6 + +# 2859| Block 6 +# 2859| v2859_1(void) = NoOp : +# 2846| v2846_10(void) = ReturnVoid : +# 2846| v2846_11(void) = AliasedUse : ~m? +# 2846| v2846_12(void) = ExitFunction : # 2864| void complex_assertions(int, bool, int) # 2864| Block 0 From 0cf33ff97359c366bada4568eaf540c9f262e748 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 9 Jan 2026 19:52:19 +0000 Subject: [PATCH 6/6] C++: Fix Code Scanning alerts. --- .../ir/implementation/raw/internal/TranslatedAssertion.qll | 2 +- .../cpp/ir/implementation/raw/internal/TranslatedStmt.qll | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll index bf058ab7f534..315062469043 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll @@ -73,7 +73,7 @@ private Function getEnclosingFunctionForMacroInvocation(MacroInvocation mi) { /** * Holds if `arg` has two components and the `i`'th component of the string - * `arg` is `s`, and the components are seperated by an operation with + * `arg` is `s`, and the components are separated by an operation with * opcode `opcode`. */ bindingset[arg] diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 82f1fd49b524..d748e2f86638 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -327,7 +327,7 @@ class TranslatedEmptyStmt extends TranslatedStmt { TranslatedEmptyStmt() { // An assertion macro invocation can expand to // an empty statement in release builds. In that case - // we synthedsize the check that would have occured. + // we synthedsize the check that would have occurred. // This is handled by `TranslatedAssertion.qll` and so // we exclude these statements here. not assertion(_, stmt) and @@ -432,7 +432,7 @@ class TranslatedExprStmt extends TranslatedStmt { TranslatedExprStmt() { // An assertion macro invocation typically expand to the // expression `((void)0)` in release builds. In that case - // we synthedsize the check that would have occured. + // we synthedsize the check that would have occurred. // This is handled by `TranslatedAssertion.qll` and so // we exclude these statements here. not assertion(_, stmt)