Merge pull request #21142 from MathiasVP/ir-support-for-assertions

C++: Generate IR for assertions in release builds
This commit is contained in:
Mathias Vorreiter Pedersen
2026-01-21 19:32:24 +00:00
committed by GitHub
14 changed files with 1688 additions and 7 deletions

View File

@@ -192,6 +192,15 @@ class Element extends ElementBase {
*/
predicate isAffectedByMacro() { affectedByMacro(this) }
/**
* INTERNAL: Do not use.
*
* 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

View File

@@ -239,6 +239,9 @@ class MacroInvocation extends MacroAccess {
macro_argument_unexpanded(underlyingElement(this), i, result)
}
/** Gets the number of arguments for this macro invocation. */
int getNumberOfArguments() { result = count(int i | exists(this.getUnexpandedArgument(i)) | i) }
/**
* Gets the `i`th _expanded_ argument of this macro invocation, where the
* first argument has `i = 0`. The result has been expanded for macros _and_

View File

@@ -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() }

View File

@@ -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"
}

View File

@@ -0,0 +1,387 @@
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.getNumberOfArguments() = 1 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, string arg) {
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
) and
arg = mi.getUnexpandedArgument(0)
}
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 separated 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("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareLE
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareGE
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareLT
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareGT
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?!=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareNE
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?==\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareEQ
}
private Element getAChildScope(Element scope) { result.getParentScope() = scope }
private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
assertion0(mi, s, _) and
s.getParent() = scope
or
hasAVariable(mi, s, getAChildScope(scope))
}
private LocalScopeVariable getVariable(MacroInvocation mi, int i) {
exists(string operand, string arg, Stmt s |
assertion0(mi, s, arg) and
parseArgument(arg, operand, i, _) and
result =
unique(Variable v |
v.getLocation().getStartLine() < s.getLocation().getStartLine() and
hasAVariable(mi, s, v.getParentScope()) and
v.hasName(operand)
|
v
)
)
}
/**
* 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
parseArgument(arg, s, i, opcode) and
var = getVariable(mi, i)
)
}
/**
* 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, _, arg) 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. */
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 }
}

View File

@@ -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`

View File

@@ -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 synthesize the check that would have occurred.
// 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 synthesize the check that would have occurred.
// 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() }

View File

@@ -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.

View File

@@ -25131,6 +25131,517 @@ 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| <params>:
# 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>(T, int, unsigned int)
# 2846| <params>:
# 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): [ExprStmt] ExprStmt
# 2859| getExpr(): [Literal] 0
# 2859| Type = [IntType] int
# 2859| Value = [Literal] 0
# 2859| ValueCategory = prvalue
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2859| getExpr(): [CStyleCast] (void)...
# 2859| Conversion = [VoidConversion] conversion to void
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2860| getStmt(7): [ReturnStmt] return ...
# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template<int>(int, int, unsigned int)
# 2846| <params>:
# 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): [ExprStmt] ExprStmt
# 2859| getExpr(): [Literal] 0
# 2859| Type = [IntType] int
# 2859| Value = [Literal] 0
# 2859| ValueCategory = prvalue
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2859| getExpr(): [CStyleCast] (void)...
# 2859| Conversion = [VoidConversion] conversion to void
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2860| getStmt(7): [ReturnStmt] return ...
# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template<short>(short, int, unsigned int)
# 2846| <params>:
# 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): [ExprStmt] ExprStmt
# 2859| getExpr(): [Literal] 0
# 2859| Type = [IntType] int
# 2859| Value = [Literal] 0
# 2859| ValueCategory = prvalue
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2859| getExpr(): [CStyleCast] (void)...
# 2859| Conversion = [VoidConversion] conversion to void
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2860| getStmt(7): [ReturnStmt] return ...
# 2867| [TopLevelFunction] void (unnamed namespace)::complex_assertions(int, bool, int)
# 2867| <params>:
# 2867| getParameter(0): [Parameter] x
# 2867| Type = [IntType] int
# 2867| getParameter(1): [Parameter] b
# 2867| Type = [BoolType] bool
# 2867| getParameter(2): [Parameter] max
# 2867| Type = [IntType] int
# 2867| getEntryPoint(): [BlockStmt] { ... }
# 2868| getStmt(0): [DeclStmt] declaration
# 2868| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 2868| Type = [IntType] int
# 2868| getVariable().getInitializer(): [Initializer] initializer for y
# 2868| getExpr(): [CommaExpr] ... , ...
# 2868| Type = [IntType] int
# 2868| ValueCategory = prvalue(load)
# 2868| getLeftOperand(): [Literal] 0
# 2868| Type = [IntType] int
# 2868| Value = [Literal] 0
# 2868| ValueCategory = prvalue
# 2868| getRightOperand(): [VariableAccess] x
# 2868| Type = [IntType] int
# 2868| ValueCategory = prvalue(load)
# 2868| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2868| Type = [VoidType] void
# 2868| ValueCategory = prvalue
# 2868| getExpr(): [CStyleCast] (void)...
# 2868| Conversion = [VoidConversion] conversion to void
# 2868| Type = [VoidType] void
# 2868| ValueCategory = prvalue
# 2868| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2868| Type = [IntType] int
# 2868| ValueCategory = prvalue(load)
# 2869| getStmt(1): [DeclStmt] declaration
# 2869| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z
# 2869| Type = [IntType] int
# 2869| getVariable().getInitializer(): [Initializer] initializer for z
# 2869| getExpr(): [ConditionalExpr] ... ? ... : ...
# 2869| Type = [IntType] int
# 2869| ValueCategory = prvalue
# 2869| getCondition(): [VariableAccess] b
# 2869| Type = [BoolType] bool
# 2869| ValueCategory = prvalue(load)
# 2869| getThen(): [CommaExpr] ... , ...
# 2869| Type = [IntType] int
# 2869| Value = [CommaExpr] 0
# 2869| ValueCategory = prvalue
# 2869| getLeftOperand(): [Literal] 0
# 2869| Type = [IntType] int
# 2869| Value = [Literal] 0
# 2869| ValueCategory = prvalue
# 2869| getRightOperand(): [Literal] 0
# 2869| Type = [IntType] int
# 2869| Value = [Literal] 0
# 2869| ValueCategory = prvalue
# 2869| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2869| Type = [VoidType] void
# 2869| ValueCategory = prvalue
# 2869| getExpr(): [CStyleCast] (void)...
# 2869| Conversion = [VoidConversion] conversion to void
# 2869| Type = [VoidType] void
# 2869| ValueCategory = prvalue
# 2869| getElse(): [Literal] 1
# 2869| Type = [IntType] int
# 2869| Value = [Literal] 1
# 2869| ValueCategory = prvalue
# 2869| getThen().getFullyConverted(): [ParenthesisExpr] (...)
# 2869| Type = [IntType] int
# 2869| Value = [ParenthesisExpr] 0
# 2869| ValueCategory = prvalue
# 2871| getStmt(2): [TryStmt] try { ... }
# 2871| getStmt(): [BlockStmt] { ... }
# 2872| getStmt(0): [ExprStmt] ExprStmt
# 2872| getExpr(): [ThrowExpr] throw ...
# 2872| Type = [IntType] int
# 2872| ValueCategory = prvalue
# 2872| getExpr(): [Literal] 41
# 2872| Type = [IntType] int
# 2872| Value = [Literal] 41
# 2872| ValueCategory = prvalue
# 2873| getChild(1): [Handler] <handler>
# 2873| getParameter(): [Parameter] c
# 2873| Type = [IntType] int
# 2873| getBlock(): [CatchBlock] { ... }
# 2874| getStmt(0): [ExprStmt] ExprStmt
# 2874| getExpr(): [Literal] 0
# 2874| Type = [IntType] int
# 2874| Value = [Literal] 0
# 2874| ValueCategory = prvalue
# 2874| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2874| Type = [VoidType] void
# 2874| ValueCategory = prvalue
# 2874| getExpr(): [CStyleCast] (void)...
# 2874| Conversion = [VoidConversion] conversion to void
# 2874| Type = [VoidType] void
# 2874| ValueCategory = prvalue
# 2875| getStmt(1): [ExprStmt] ExprStmt
# 2875| getExpr(): [Literal] 0
# 2875| Type = [IntType] int
# 2875| Value = [Literal] 0
# 2875| ValueCategory = prvalue
# 2875| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2875| Type = [VoidType] void
# 2875| ValueCategory = prvalue
# 2875| getExpr(): [CStyleCast] (void)...
# 2875| Conversion = [VoidConversion] conversion to void
# 2875| Type = [VoidType] void
# 2875| ValueCategory = prvalue
# 2878| getStmt(3): [ExprStmt] ExprStmt
# 2878| getExpr(): [Literal] 0
# 2878| Type = [IntType] int
# 2878| Value = [Literal] 0
# 2878| ValueCategory = prvalue
# 2878| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2878| Type = [VoidType] void
# 2878| ValueCategory = prvalue
# 2878| getExpr(): [CStyleCast] (void)...
# 2878| Conversion = [VoidConversion] conversion to void
# 2878| Type = [VoidType] void
# 2878| ValueCategory = prvalue
# 2879| getStmt(4): [DeclStmt] declaration
# 2879| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
# 2879| Type = [IntType] int
# 2881| getStmt(5): [TryStmt] try { ... }
# 2881| getStmt(): [BlockStmt] { ... }
# 2882| getStmt(0): [ExprStmt] ExprStmt
# 2882| getExpr(): [ThrowExpr] throw ...
# 2882| Type = [IntType] int
# 2882| ValueCategory = prvalue
# 2882| getExpr(): [Literal] 41
# 2882| Type = [IntType] int
# 2882| Value = [Literal] 41
# 2882| ValueCategory = prvalue
# 2883| getChild(1): [Handler] <handler>
# 2883| getParameter(): [Parameter] shadowed
# 2883| Type = [IntType] int
# 2883| getBlock(): [CatchBlock] { ... }
# 2884| getStmt(0): [ExprStmt] ExprStmt
# 2884| getExpr(): [Literal] 0
# 2884| Type = [IntType] int
# 2884| Value = [Literal] 0
# 2884| ValueCategory = prvalue
# 2884| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2884| Type = [VoidType] void
# 2884| ValueCategory = prvalue
# 2884| getExpr(): [CStyleCast] (void)...
# 2884| Conversion = [VoidConversion] conversion to void
# 2884| Type = [VoidType] void
# 2884| ValueCategory = prvalue
# 2886| getStmt(6): [ReturnStmt] return ...
ir23.cpp:
# 1| [TopLevelFunction] bool consteval_1()
# 1| <params>:

View File

@@ -20741,6 +20741,331 @@ 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<int>) = VariableAddress[x] :
# 2830| m2830_6(int) = InitializeParameter[x] : &:r2830_5
# 2830| r2830_7(glval<int>) = VariableAddress[y] :
# 2830| m2830_8(int) = InitializeParameter[y] : &:r2830_7
# 2830| r2830_9(glval<unsigned int>) = VariableAddress[u] :
# 2830| m2830_10(unsigned int) = InitializeParameter[u] : &:r2830_9
# 2830| r2830_11(glval<int>) = VariableAddress[shadowed] :
# 2830| m2830_12(int) = InitializeParameter[shadowed] : &:r2830_11
# 2831| r2831_1(glval<int>) = 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<int>) = 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<int>) = VariableAddress[x] :
# 2833| r2833_2(int) = Load[x] : &:r2833_1, m2830_6
# 2833| r2833_3(glval<int>) = 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<int>) = 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<unsigned int>) = VariableAddress[u] :
# 2837| r2837_2(unsigned int) = Load[u] : &:r2837_1, m2830_10
# 2837| r2837_3(glval<int>) = 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<int>) = VariableAddress[shadowed] :
# 2840| r2840_2(glval<int>) = 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, 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<int>) = VariableAddress[x] :
# 2846| m2846_6(int) = InitializeParameter[x] : &:r2846_5
# 2846| r2846_7(glval<int>) = VariableAddress[y] :
# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7
# 2846| r2846_9(glval<unsigned int>) = VariableAddress[u] :
# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9
# 2847| r2847_1(glval<int>) = 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<int>) = 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<int>) = VariableAddress[x] :
# 2849| r2849_2(int) = Load[x] : &:r2849_1, m2846_6
# 2849| r2849_3(glval<int>) = 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<int>) = 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<unsigned int>) = VariableAddress[u] :
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10
# 2853| r2853_3(glval<int>) = 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<int>) = VariableAddress[shadowed] :
# 2856| r2856_2(glval<int>) = 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<int>) = 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| r2859_1(glval<int>) = VariableAddress[x] :
# 2859| r2859_2(int) = Load[x] : &:r2859_1, m2846_6
# 2859| r2859_3(int) = Constant[0] :
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
#-----| True -> Block 7
# 2860| Block 7
# 2860| v2860_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>(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<short>) = VariableAddress[x] :
# 2846| m2846_6(short) = InitializeParameter[x] : &:r2846_5
# 2846| r2846_7(glval<int>) = VariableAddress[y] :
# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7
# 2846| r2846_9(glval<unsigned int>) = VariableAddress[u] :
# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9
# 2847| r2847_1(glval<short>) = 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<short>) = 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<short>) = VariableAddress[x] :
# 2849| r2849_2(short) = Load[x] : &:r2849_1, m2846_6
# 2849| r2849_3(glval<int>) = 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<short>) = 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<unsigned int>) = VariableAddress[u] :
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10
# 2853| r2853_3(glval<short>) = 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<int>) = VariableAddress[shadowed] :
# 2856| r2856_2(glval<short>) = 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<int>) = 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| r2859_1(glval<short>) = VariableAddress[x] :
# 2859| r2859_2(short) = Load[x] : &:r2859_1, m2846_6
# 2859| r2859_3(int) = Constant[0] :
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
#-----| True -> Block 7
# 2860| Block 7
# 2860| v2860_1(void) = NoOp :
# 2846| v2846_11(void) = ReturnVoid :
# 2846| v2846_12(void) = AliasedUse : m2846_3
# 2846| v2846_13(void) = ExitFunction :
# 2867| void (unnamed namespace)::complex_assertions(int, bool, int)
# 2867| Block 0
# 2867| v2867_1(void) = EnterFunction :
# 2867| m2867_2(unknown) = AliasedDefinition :
# 2867| m2867_3(unknown) = InitializeNonLocal :
# 2867| m2867_4(unknown) = Chi : total:m2867_2, partial:m2867_3
# 2867| r2867_5(glval<int>) = VariableAddress[x] :
# 2867| m2867_6(int) = InitializeParameter[x] : &:r2867_5
# 2867| r2867_7(glval<bool>) = VariableAddress[b] :
# 2867| m2867_8(bool) = InitializeParameter[b] : &:r2867_7
# 2867| r2867_9(glval<int>) = VariableAddress[max] :
# 2867| m2867_10(int) = InitializeParameter[max] : &:r2867_9
# 2868| r2868_1(glval<int>) = VariableAddress[y] :
# 2868| r2868_2(int) = Constant[0] :
# 2868| v2868_3(void) = Convert : r2868_2
# 2868| r2868_4(glval<int>) = VariableAddress[x] :
# 2868| r2868_5(int) = Load[x] : &:r2868_4, m2867_6
# 2868| r2868_6(int) = CopyValue : r2868_5
# 2868| m2868_7(int) = Store[y] : &:r2868_1, r2868_6
# 2869| r2869_1(glval<int>) = VariableAddress[z] :
# 2869| r2869_2(glval<bool>) = VariableAddress[b] :
# 2869| r2869_3(bool) = Load[b] : &:r2869_2, m2867_8
# 2869| v2869_4(void) = ConditionalBranch : r2869_3
#-----| False -> Block 5
#-----| True -> Block 4
# 2867| Block 1
# 2867| v2867_11(void) = AliasedUse : m2867_3
# 2867| v2867_12(void) = ExitFunction :
# 2867| Block 2
# 2867| v2867_13(void) = Unwind :
#-----| Goto -> Block 1
# 2869| Block 3
# 2869| m2869_5(int) = Phi : from 4:m2869_11, from 5:m2869_14
# 2869| r2869_6(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| r2869_7(int) = Load[#temp2869:17] : &:r2869_6, m2869_5
# 2869| m2869_8(int) = Store[z] : &:r2869_1, r2869_7
# 2872| r2872_1(glval<int>) = VariableAddress[#throw2872:13] :
# 2872| r2872_2(int) = Constant[41] :
# 2872| m2872_3(int) = Store[#throw2872:13] : &:r2872_1, r2872_2
# 2872| v2872_4(void) = ThrowValue : &:r2872_1, m2872_3
#-----| C++ Exception -> Block 6
# 2869| Block 4
# 2869| r2869_9(int) = Constant[0] :
# 2869| r2869_10(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| m2869_11(int) = Store[#temp2869:17] : &:r2869_10, r2869_9
#-----| Goto -> Block 3
# 2869| Block 5
# 2869| r2869_12(int) = Constant[1] :
# 2869| r2869_13(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| m2869_14(int) = Store[#temp2869:17] : &:r2869_13, r2869_12
#-----| Goto -> Block 3
# 2873| Block 6
# 2873| v2873_1(void) = CatchByType[int] :
#-----| C++ Exception -> Block 2
#-----| Goto -> Block 7
# 2873| Block 7
# 2873| r2873_2(glval<int>) = VariableAddress[c] :
# 2873| m2873_3(int) = InitializeParameter[c] : &:r2873_2
# 2874| r2874_1(glval<int>) = VariableAddress[c] :
# 2874| r2874_2(int) = Load[c] : &:r2874_1, m2873_3
# 2874| r2874_3(int) = Constant[42] :
# 2874| r2874_4(bool) = CompareLT : r2874_2, r2874_3
# 2874| v2874_5(void) = ConditionalBranch : r2874_4
#-----| True -> Block 8
# 2875| Block 8
# 2875| r2875_1(int) = Constant[0] :
# 2875| v2875_2(void) = Convert : r2875_1
# 2878| r2878_1(int) = Constant[0] :
# 2878| v2878_2(void) = Convert : r2878_1
# 2879| r2879_1(glval<int>) = VariableAddress[shadowed] :
# 2879| m2879_2(int) = Uninitialized[shadowed] : &:r2879_1
# 2882| r2882_1(glval<int>) = VariableAddress[#throw2882:13] :
# 2882| r2882_2(int) = Constant[41] :
# 2882| m2882_3(int) = Store[#throw2882:13] : &:r2882_1, r2882_2
# 2882| v2882_4(void) = ThrowValue : &:r2882_1, m2882_3
#-----| C++ Exception -> Block 9
# 2883| Block 9
# 2883| v2883_1(void) = CatchByType[int] :
#-----| C++ Exception -> Block 2
#-----| Goto -> Block 10
# 2883| Block 10
# 2883| r2883_2(glval<int>) = VariableAddress[shadowed] :
# 2883| m2883_3(int) = InitializeParameter[shadowed] : &:r2883_2
# 2884| r2884_1(int) = Constant[0] :
# 2884| v2884_2(void) = Convert : r2884_1
# 2886| v2886_1(void) = NoOp :
# 2867| v2867_14(void) = ReturnVoid :
#-----| Goto -> Block 1
ir23.cpp:
# 1| bool consteval_1()
# 1| Block 0

View File

@@ -0,0 +1,20 @@
import cpp
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedAssertion
import utils.test.InlineExpectationsTest
module Test implements TestSig {
string getARelevantTag() { result = "var" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TranslatedAssertionVarAccess tava, Variable v |
v = tava.getVariable() and
location = tava.getLocation() and
tava.toString() = element and
tag = "var" and
value = v.getLocation().getStartLine().toString() + ":" + v.getName()
)
}
}
import MakeTest<Test>

View File

@@ -2823,4 +2823,67 @@ 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); // $ var=2830:x
assert(0 < x); // $ var=2830:x
assert(x < y); // $ var=2830:x var=2830:y
__analysis_assume(x != 2); // $ var=2830:x
assert(u < x); // $ var=2830:u var=2830:x
{
int shadowed = x;
assert(shadowed > 0); // no assertion generated since the variable is shadowed
}
}
template<typename T>
void test_assert_in_template(T x, int y, unsigned u) {
assert(x > 0); // $ var=2846:x
assert(0 < x); // $ var=2846:x
assert(x < y); // $ var=2846:x var=2846:y
__analysis_assume(x != 2); // $ var=2846:x
assert(u < x); // $ var=2846:u var=2846:x
{
int shadowed = x;
assert(shadowed > 0); // $ var=2856:shadowed
}
assert(x> 0); // $ var=2846:x
}
template void test_assert_in_template<int>(int, int, unsigned);
template void test_assert_in_template<short>(short, int, unsigned);
namespace {
int shadowed;
void complex_assertions(int x, bool b, int max) {
int y = (assert(x > 0), x); // no assertion generated
int z = b ? (assert(x != 0), 0) : 1; // no assertion generated
try {
throw 41;
} catch (int c) {
assert(c < 42); // $ var=2873:c
assert(shadowed < 42); // no assertion generated
}
assert(shadowed > 0); // no assertion generated
int shadowed;
try {
throw 41;
} catch (int shadowed) {
assert(shadowed < 42); // no assertion generated
}
}
}
// semmle-extractor-options: -std=c++20 --clang

View File

@@ -18880,6 +18880,326 @@ 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<int>) = VariableAddress[x] :
# 2830| mu2830_5(int) = InitializeParameter[x] : &:r2830_4
# 2830| r2830_6(glval<int>) = VariableAddress[y] :
# 2830| mu2830_7(int) = InitializeParameter[y] : &:r2830_6
# 2830| r2830_8(glval<unsigned int>) = VariableAddress[u] :
# 2830| mu2830_9(unsigned int) = InitializeParameter[u] : &:r2830_8
# 2830| r2830_10(glval<int>) = VariableAddress[shadowed] :
# 2830| mu2830_11(int) = InitializeParameter[shadowed] : &:r2830_10
# 2831| r2831_1(glval<int>) = 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<int>) = 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<int>) = VariableAddress[x] :
# 2833| r2833_2(int) = Load[x] : &:r2833_1, ~m?
# 2833| r2833_3(glval<int>) = 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<int>) = 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<unsigned int>) = VariableAddress[u] :
# 2837| r2837_2(unsigned int) = Load[u] : &:r2837_1, ~m?
# 2837| r2837_3(glval<int>) = 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<int>) = VariableAddress[shadowed] :
# 2840| r2840_2(glval<int>) = 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, 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<int>) = VariableAddress[x] :
# 2846| mu2846_5(int) = InitializeParameter[x] : &:r2846_4
# 2846| r2846_6(glval<int>) = VariableAddress[y] :
# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6
# 2846| r2846_8(glval<unsigned int>) = VariableAddress[u] :
# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8
# 2847| r2847_1(glval<int>) = 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<int>) = 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<int>) = VariableAddress[x] :
# 2849| r2849_2(int) = Load[x] : &:r2849_1, ~m?
# 2849| r2849_3(glval<int>) = 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<int>) = 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<unsigned int>) = VariableAddress[u] :
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, ~m?
# 2853| r2853_3(glval<int>) = 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<int>) = VariableAddress[shadowed] :
# 2856| r2856_2(glval<int>) = 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<int>) = 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| r2859_1(glval<int>) = VariableAddress[x] :
# 2859| r2859_2(int) = Load[x] : &:r2859_1, ~m?
# 2859| r2859_3(int) = Constant[0] :
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
#-----| True -> Block 7
# 2860| Block 7
# 2860| v2860_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>(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<short>) = VariableAddress[x] :
# 2846| mu2846_5(short) = InitializeParameter[x] : &:r2846_4
# 2846| r2846_6(glval<int>) = VariableAddress[y] :
# 2846| mu2846_7(int) = InitializeParameter[y] : &:r2846_6
# 2846| r2846_8(glval<unsigned int>) = VariableAddress[u] :
# 2846| mu2846_9(unsigned int) = InitializeParameter[u] : &:r2846_8
# 2847| r2847_1(glval<short>) = 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<short>) = 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<short>) = VariableAddress[x] :
# 2849| r2849_2(short) = Load[x] : &:r2849_1, ~m?
# 2849| r2849_3(glval<int>) = 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<short>) = 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<unsigned int>) = VariableAddress[u] :
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, ~m?
# 2853| r2853_3(glval<short>) = 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<int>) = VariableAddress[shadowed] :
# 2856| r2856_2(glval<short>) = 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<int>) = 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| r2859_1(glval<short>) = VariableAddress[x] :
# 2859| r2859_2(short) = Load[x] : &:r2859_1, ~m?
# 2859| r2859_3(int) = Constant[0] :
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
#-----| True -> Block 7
# 2860| Block 7
# 2860| v2860_1(void) = NoOp :
# 2846| v2846_10(void) = ReturnVoid :
# 2846| v2846_11(void) = AliasedUse : ~m?
# 2846| v2846_12(void) = ExitFunction :
# 2867| void (unnamed namespace)::complex_assertions(int, bool, int)
# 2867| Block 0
# 2867| v2867_1(void) = EnterFunction :
# 2867| mu2867_2(unknown) = AliasedDefinition :
# 2867| mu2867_3(unknown) = InitializeNonLocal :
# 2867| r2867_4(glval<int>) = VariableAddress[x] :
# 2867| mu2867_5(int) = InitializeParameter[x] : &:r2867_4
# 2867| r2867_6(glval<bool>) = VariableAddress[b] :
# 2867| mu2867_7(bool) = InitializeParameter[b] : &:r2867_6
# 2867| r2867_8(glval<int>) = VariableAddress[max] :
# 2867| mu2867_9(int) = InitializeParameter[max] : &:r2867_8
# 2868| r2868_1(glval<int>) = VariableAddress[y] :
# 2868| r2868_2(int) = Constant[0] :
# 2868| v2868_3(void) = Convert : r2868_2
# 2868| r2868_4(glval<int>) = VariableAddress[x] :
# 2868| r2868_5(int) = Load[x] : &:r2868_4, ~m?
# 2868| r2868_6(int) = CopyValue : r2868_5
# 2868| mu2868_7(int) = Store[y] : &:r2868_1, r2868_6
# 2869| r2869_1(glval<int>) = VariableAddress[z] :
# 2869| r2869_2(glval<bool>) = VariableAddress[b] :
# 2869| r2869_3(bool) = Load[b] : &:r2869_2, ~m?
# 2869| v2869_4(void) = ConditionalBranch : r2869_3
#-----| False -> Block 5
#-----| True -> Block 4
# 2867| Block 1
# 2867| v2867_10(void) = AliasedUse : ~m?
# 2867| v2867_11(void) = ExitFunction :
# 2867| Block 2
# 2867| v2867_12(void) = Unwind :
#-----| Goto -> Block 1
# 2869| Block 3
# 2869| r2869_5(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| r2869_6(int) = Load[#temp2869:17] : &:r2869_5, ~m?
# 2869| mu2869_7(int) = Store[z] : &:r2869_1, r2869_6
# 2872| r2872_1(glval<int>) = VariableAddress[#throw2872:13] :
# 2872| r2872_2(int) = Constant[41] :
# 2872| mu2872_3(int) = Store[#throw2872:13] : &:r2872_1, r2872_2
# 2872| v2872_4(void) = ThrowValue : &:r2872_1, ~m?
#-----| C++ Exception -> Block 6
# 2869| Block 4
# 2869| r2869_8(int) = Constant[0] :
# 2869| r2869_9(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| mu2869_10(int) = Store[#temp2869:17] : &:r2869_9, r2869_8
#-----| Goto -> Block 3
# 2869| Block 5
# 2869| r2869_11(int) = Constant[1] :
# 2869| r2869_12(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| mu2869_13(int) = Store[#temp2869:17] : &:r2869_12, r2869_11
#-----| Goto -> Block 3
# 2873| Block 6
# 2873| v2873_1(void) = CatchByType[int] :
#-----| C++ Exception -> Block 2
#-----| Goto -> Block 7
# 2873| Block 7
# 2873| r2873_2(glval<int>) = VariableAddress[c] :
# 2873| mu2873_3(int) = InitializeParameter[c] : &:r2873_2
# 2874| r2874_1(glval<int>) = VariableAddress[c] :
# 2874| r2874_2(int) = Load[c] : &:r2874_1, ~m?
# 2874| r2874_3(int) = Constant[42] :
# 2874| r2874_4(bool) = CompareLT : r2874_2, r2874_3
# 2874| v2874_5(void) = ConditionalBranch : r2874_4
#-----| True -> Block 8
# 2875| Block 8
# 2875| r2875_1(int) = Constant[0] :
# 2875| v2875_2(void) = Convert : r2875_1
# 2878| r2878_1(int) = Constant[0] :
# 2878| v2878_2(void) = Convert : r2878_1
# 2879| r2879_1(glval<int>) = VariableAddress[shadowed] :
# 2879| mu2879_2(int) = Uninitialized[shadowed] : &:r2879_1
# 2882| r2882_1(glval<int>) = VariableAddress[#throw2882:13] :
# 2882| r2882_2(int) = Constant[41] :
# 2882| mu2882_3(int) = Store[#throw2882:13] : &:r2882_1, r2882_2
# 2882| v2882_4(void) = ThrowValue : &:r2882_1, ~m?
#-----| C++ Exception -> Block 9
# 2883| Block 9
# 2883| v2883_1(void) = CatchByType[int] :
#-----| C++ Exception -> Block 2
#-----| Goto -> Block 10
# 2883| Block 10
# 2883| r2883_2(glval<int>) = VariableAddress[shadowed] :
# 2883| mu2883_3(int) = InitializeParameter[shadowed] : &:r2883_2
# 2884| r2884_1(int) = Constant[0] :
# 2884| v2884_2(void) = Convert : r2884_1
# 2886| v2886_1(void) = NoOp :
# 2867| v2867_13(void) = ReturnVoid :
#-----| Goto -> Block 1
ir23.cpp:
# 1| bool consteval_1()
# 1| Block 0