mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
C++: handle calls to noreturn functions
This commit is contained in:
@@ -19,6 +19,9 @@ newtype TInstruction =
|
||||
) {
|
||||
IRConstruction::Raw::hasInstruction(tag1, tag2)
|
||||
} or
|
||||
TRawUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
IRConstruction::hasUnreachedInstruction(irFunc)
|
||||
} or
|
||||
TUnaliasedSsaPhiInstruction(
|
||||
TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation
|
||||
) {
|
||||
|
||||
@@ -178,7 +178,7 @@ module Raw {
|
||||
}
|
||||
}
|
||||
|
||||
class TStageInstruction = TRawInstruction;
|
||||
class TStageInstruction = TRawInstruction or TRawUnreachedInstruction;
|
||||
|
||||
predicate hasInstruction(TRawInstruction instr) { any() }
|
||||
|
||||
@@ -393,6 +393,16 @@ Instruction getPrimaryInstructionForSideEffect(SideEffectInstruction instruction
|
||||
.getPrimaryInstructionForSideEffect(getInstructionTag(instruction))
|
||||
}
|
||||
|
||||
predicate hasUnreachedInstruction(IRFunction func) {
|
||||
exists(Call c |
|
||||
c.getEnclosingFunction() = func.getFunction() and
|
||||
(
|
||||
c.getTarget().hasSpecifier("_Noreturn") or
|
||||
c.getTarget().getAnAttribute().hasName("noreturn")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
import CachedForDebugging
|
||||
|
||||
cached
|
||||
|
||||
@@ -34,6 +34,7 @@ newtype TInstructionTag =
|
||||
CallTargetTag() or
|
||||
CallTag() or
|
||||
CallSideEffectTag() or
|
||||
CallNoReturnTag() or
|
||||
AllocationSizeTag() or
|
||||
AllocationElementSizeTag() or
|
||||
AllocationExtentConvertTag() or
|
||||
|
||||
@@ -66,7 +66,9 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
)
|
||||
or
|
||||
child = getSideEffects() and
|
||||
result = getParent().getChildSuccessor(this)
|
||||
if this.isNoReturn()
|
||||
then result = any(UnreachedInstruction instr | this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction())
|
||||
else result = getParent().getChildSuccessor(this)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
@@ -161,6 +163,10 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
*/
|
||||
abstract predicate hasArguments();
|
||||
|
||||
predicate isNoReturn() {
|
||||
none()
|
||||
}
|
||||
|
||||
final TranslatedSideEffects getSideEffects() { result.getExpr() = expr }
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
|
||||
conditionValue = getConstantValue(instr.(ConditionalBranchInstruction).getCondition()) and
|
||||
if conditionValue = 0 then kind instanceof TrueEdge else kind instanceof FalseEdge
|
||||
)
|
||||
or
|
||||
instr.getSuccessor(kind) instanceof UnreachedInstruction and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -41,7 +44,9 @@ class ReachableBlock extends IRBlockBase {
|
||||
* An instruction that is contained in a reachable block.
|
||||
*/
|
||||
class ReachableInstruction extends Instruction {
|
||||
ReachableInstruction() { this.getBlock() instanceof ReachableBlock }
|
||||
ReachableInstruction() {
|
||||
this.getBlock() instanceof ReachableBlock and not this instanceof UnreachedInstruction
|
||||
}
|
||||
}
|
||||
|
||||
module Graph {
|
||||
|
||||
@@ -34,9 +34,13 @@ private module Cached {
|
||||
|
||||
cached
|
||||
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
exists(OldIR::Instruction oldInstruction |
|
||||
irFunc = oldInstruction.getEnclosingIRFunction() and
|
||||
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
|
||||
(
|
||||
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
|
||||
or
|
||||
oldInstruction.getOpcode() instanceof Opcode::Unreached
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
|
||||
conditionValue = getConstantValue(instr.(ConditionalBranchInstruction).getCondition()) and
|
||||
if conditionValue = 0 then kind instanceof TrueEdge else kind instanceof FalseEdge
|
||||
)
|
||||
or
|
||||
instr.getSuccessor(kind) instanceof UnreachedInstruction and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -41,7 +44,9 @@ class ReachableBlock extends IRBlockBase {
|
||||
* An instruction that is contained in a reachable block.
|
||||
*/
|
||||
class ReachableInstruction extends Instruction {
|
||||
ReachableInstruction() { this.getBlock() instanceof ReachableBlock }
|
||||
ReachableInstruction() {
|
||||
this.getBlock() instanceof ReachableBlock and not this instanceof UnreachedInstruction
|
||||
}
|
||||
}
|
||||
|
||||
module Graph {
|
||||
|
||||
@@ -14408,6 +14408,35 @@ ir.cpp:
|
||||
# 1894| Conversion = [IntegralConversion] integral conversion
|
||||
# 1894| Type = [IntType] int
|
||||
# 1894| ValueCategory = prvalue
|
||||
# 1897| [TopLevelFunction] void noreturnFunc()
|
||||
# 1897| <params>:
|
||||
# 1899| [TopLevelFunction] int noreturnTest(int)
|
||||
# 1899| <params>:
|
||||
# 1899| getParameter(0): [Parameter] x
|
||||
# 1899| Type = [IntType] int
|
||||
# 1899| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1900| getStmt(0): [IfStmt] if (...) ...
|
||||
# 1900| getCondition(): [LTExpr] ... < ...
|
||||
# 1900| Type = [BoolType] bool
|
||||
# 1900| ValueCategory = prvalue
|
||||
# 1900| getLesserOperand(): [VariableAccess] x
|
||||
# 1900| Type = [IntType] int
|
||||
# 1900| ValueCategory = prvalue(load)
|
||||
# 1900| getGreaterOperand(): [Literal] 10
|
||||
# 1900| Type = [IntType] int
|
||||
# 1900| Value = [Literal] 10
|
||||
# 1900| ValueCategory = prvalue
|
||||
# 1900| getThen(): [BlockStmt] { ... }
|
||||
# 1901| getStmt(0): [ReturnStmt] return ...
|
||||
# 1901| getExpr(): [VariableAccess] x
|
||||
# 1901| Type = [IntType] int
|
||||
# 1901| ValueCategory = prvalue(load)
|
||||
# 1902| getElse(): [BlockStmt] { ... }
|
||||
# 1903| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 1903| getExpr(): [FunctionCall] call to noreturnFunc
|
||||
# 1903| Type = [VoidType] void
|
||||
# 1903| ValueCategory = prvalue
|
||||
# 1905| getStmt(1): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -6,6 +6,8 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ir.cpp:1754:41:1754:42 | Chi: call to CopyConstructorTestVirtualClass | Instruction 'Chi: call to CopyConstructorTestVirtualClass' has no successors in function '$@'. | ir.cpp:1750:5:1750:34 | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) |
|
||||
| ir.cpp:1903:9:1903:20 | Chi: call to noreturnFunc | Instruction 'Chi: call to noreturnFunc' has no successors in function '$@'. | ir.cpp:1899:5:1899:16 | int noreturnTest(int) | int noreturnTest(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -6,6 +6,8 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ir.cpp:1754:41:1754:42 | Chi: call to CopyConstructorTestVirtualClass | Instruction 'Chi: call to CopyConstructorTestVirtualClass' has no successors in function '$@'. | ir.cpp:1750:5:1750:34 | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) |
|
||||
| ir.cpp:1903:9:1903:20 | Chi: call to noreturnFunc | Instruction 'Chi: call to noreturnFunc' has no successors in function '$@'. | ir.cpp:1899:5:1899:16 | int noreturnTest(int) | int noreturnTest(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -1894,4 +1894,14 @@ int test_global_template_int() {
|
||||
return local_int + (int)local_char;
|
||||
}
|
||||
|
||||
[[noreturn]] void noreturnFunc();
|
||||
|
||||
int noreturnTest(int x) {
|
||||
if (x < 10) {
|
||||
return x;
|
||||
} else {
|
||||
noreturnFunc();
|
||||
}
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -8783,6 +8783,25 @@
|
||||
| ir.cpp:1894:29:1894:38 | Address | &:r1894_4 |
|
||||
| ir.cpp:1894:29:1894:38 | Load | m1893_4 |
|
||||
| ir.cpp:1894:29:1894:38 | Unary | r1894_5 |
|
||||
| ir.cpp:1899:5:1899:16 | Address | &:r1899_7 |
|
||||
| ir.cpp:1899:5:1899:16 | ChiPartial | partial:m1899_3 |
|
||||
| ir.cpp:1899:5:1899:16 | ChiTotal | total:m1899_2 |
|
||||
| ir.cpp:1899:5:1899:16 | Load | m1901_4 |
|
||||
| ir.cpp:1899:5:1899:16 | SideEffect | m1899_3 |
|
||||
| ir.cpp:1899:22:1899:22 | Address | &:r1899_5 |
|
||||
| ir.cpp:1900:9:1900:9 | Address | &:r1900_1 |
|
||||
| ir.cpp:1900:9:1900:9 | Left | r1900_2 |
|
||||
| ir.cpp:1900:9:1900:9 | Load | m1899_6 |
|
||||
| ir.cpp:1900:9:1900:14 | Condition | r1900_4 |
|
||||
| ir.cpp:1900:13:1900:14 | Right | r1900_3 |
|
||||
| ir.cpp:1901:9:1901:17 | Address | &:r1901_1 |
|
||||
| ir.cpp:1901:16:1901:16 | Address | &:r1901_2 |
|
||||
| ir.cpp:1901:16:1901:16 | Load | m1899_6 |
|
||||
| ir.cpp:1901:16:1901:16 | StoreValue | r1901_3 |
|
||||
| ir.cpp:1903:9:1903:20 | CallTarget | func:r1903_1 |
|
||||
| ir.cpp:1903:9:1903:20 | ChiPartial | partial:m1903_3 |
|
||||
| ir.cpp:1903:9:1903:20 | ChiTotal | total:m1899_4 |
|
||||
| ir.cpp:1903:9:1903:20 | SideEffect | ~m1899_4 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
|
||||
|
||||
@@ -10105,6 +10105,37 @@ ir.cpp:
|
||||
# 1891| v1891_6(void) = AliasedUse : ~m?
|
||||
# 1891| v1891_7(void) = ExitFunction :
|
||||
|
||||
# 1899| int noreturnTest(int)
|
||||
# 1899| Block 0
|
||||
# 1899| v1899_1(void) = EnterFunction :
|
||||
# 1899| mu1899_2(unknown) = AliasedDefinition :
|
||||
# 1899| mu1899_3(unknown) = InitializeNonLocal :
|
||||
# 1899| r1899_4(glval<int>) = VariableAddress[x] :
|
||||
# 1899| mu1899_5(int) = InitializeParameter[x] : &:r1899_4
|
||||
# 1900| r1900_1(glval<int>) = VariableAddress[x] :
|
||||
# 1900| r1900_2(int) = Load[x] : &:r1900_1, ~m?
|
||||
# 1900| r1900_3(int) = Constant[10] :
|
||||
# 1900| r1900_4(bool) = CompareLT : r1900_2, r1900_3
|
||||
# 1900| v1900_5(void) = ConditionalBranch : r1900_4
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 1901| Block 1
|
||||
# 1901| r1901_1(glval<int>) = VariableAddress[#return] :
|
||||
# 1901| r1901_2(glval<int>) = VariableAddress[x] :
|
||||
# 1901| r1901_3(int) = Load[x] : &:r1901_2, ~m?
|
||||
# 1901| mu1901_4(int) = Store[#return] : &:r1901_1, r1901_3
|
||||
# 1899| r1899_6(glval<int>) = VariableAddress[#return] :
|
||||
# 1899| v1899_7(void) = ReturnValue : &:r1899_6, ~m?
|
||||
# 1899| v1899_8(void) = AliasedUse : ~m?
|
||||
# 1899| v1899_9(void) = ExitFunction :
|
||||
|
||||
# 1903| Block 2
|
||||
# 1903| r1903_1(glval<unknown>) = FunctionAddress[noreturnFunc] :
|
||||
# 1903| v1903_2(void) = Call[noreturnFunc] : func:r1903_1
|
||||
# 1903| mu1903_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 1905| v1905_1(void) = Unreached :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -6,6 +6,7 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ssa.cpp:427:9:427:20 | Chi: call to noreturnFunc | Instruction 'Chi: call to noreturnFunc' has no successors in function '$@'. | ssa.cpp:423:5:423:16 | int noreturnTest(int) | int noreturnTest(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -6,6 +6,7 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ssa.cpp:427:9:427:20 | Chi: call to noreturnFunc | Instruction 'Chi: call to noreturnFunc' has no successors in function '$@'. | ssa.cpp:423:5:423:16 | int noreturnTest(int) | int noreturnTest(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -2091,3 +2091,38 @@ ssa.cpp:
|
||||
# 417| v417_5(void) = ReturnVoid :
|
||||
# 417| v417_6(void) = AliasedUse : m417_3
|
||||
# 417| v417_7(void) = ExitFunction :
|
||||
|
||||
# 423| int noreturnTest(int)
|
||||
# 423| Block 0
|
||||
# 423| v423_1(void) = EnterFunction :
|
||||
# 423| m423_2(unknown) = AliasedDefinition :
|
||||
# 423| m423_3(unknown) = InitializeNonLocal :
|
||||
# 423| m423_4(unknown) = Chi : total:m423_2, partial:m423_3
|
||||
# 423| r423_5(glval<int>) = VariableAddress[x] :
|
||||
# 423| m423_6(int) = InitializeParameter[x] : &:r423_5
|
||||
# 424| r424_1(glval<int>) = VariableAddress[x] :
|
||||
# 424| r424_2(int) = Load[x] : &:r424_1, m423_6
|
||||
# 424| r424_3(int) = Constant[10] :
|
||||
# 424| r424_4(bool) = CompareLT : r424_2, r424_3
|
||||
# 424| v424_5(void) = ConditionalBranch : r424_4
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 425| Block 1
|
||||
# 425| r425_1(glval<int>) = VariableAddress[#return] :
|
||||
# 425| r425_2(glval<int>) = VariableAddress[x] :
|
||||
# 425| r425_3(int) = Load[x] : &:r425_2, m423_6
|
||||
# 425| m425_4(int) = Store[#return] : &:r425_1, r425_3
|
||||
# 423| r423_7(glval<int>) = VariableAddress[#return] :
|
||||
# 423| v423_8(void) = ReturnValue : &:r423_7, m425_4
|
||||
# 423| v423_9(void) = AliasedUse : m423_3
|
||||
# 423| v423_10(void) = ExitFunction :
|
||||
|
||||
# 427| Block 2
|
||||
# 427| r427_1(glval<unknown>) = FunctionAddress[noreturnFunc] :
|
||||
# 427| v427_2(void) = Call[noreturnFunc] : func:r427_1
|
||||
# 427| m427_3(unknown) = ^CallSideEffect : ~m423_4
|
||||
# 427| m427_4(unknown) = Chi : total:m423_4, partial:m427_3
|
||||
|
||||
# 423| Block 3
|
||||
# 423| v423_11(void) = Unreached :
|
||||
|
||||
@@ -2080,3 +2080,38 @@ ssa.cpp:
|
||||
# 417| v417_5(void) = ReturnVoid :
|
||||
# 417| v417_6(void) = AliasedUse : m417_3
|
||||
# 417| v417_7(void) = ExitFunction :
|
||||
|
||||
# 423| int noreturnTest(int)
|
||||
# 423| Block 0
|
||||
# 423| v423_1(void) = EnterFunction :
|
||||
# 423| m423_2(unknown) = AliasedDefinition :
|
||||
# 423| m423_3(unknown) = InitializeNonLocal :
|
||||
# 423| m423_4(unknown) = Chi : total:m423_2, partial:m423_3
|
||||
# 423| r423_5(glval<int>) = VariableAddress[x] :
|
||||
# 423| m423_6(int) = InitializeParameter[x] : &:r423_5
|
||||
# 424| r424_1(glval<int>) = VariableAddress[x] :
|
||||
# 424| r424_2(int) = Load[x] : &:r424_1, m423_6
|
||||
# 424| r424_3(int) = Constant[10] :
|
||||
# 424| r424_4(bool) = CompareLT : r424_2, r424_3
|
||||
# 424| v424_5(void) = ConditionalBranch : r424_4
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 425| Block 1
|
||||
# 425| r425_1(glval<int>) = VariableAddress[#return] :
|
||||
# 425| r425_2(glval<int>) = VariableAddress[x] :
|
||||
# 425| r425_3(int) = Load[x] : &:r425_2, m423_6
|
||||
# 425| m425_4(int) = Store[#return] : &:r425_1, r425_3
|
||||
# 423| r423_7(glval<int>) = VariableAddress[#return] :
|
||||
# 423| v423_8(void) = ReturnValue : &:r423_7, m425_4
|
||||
# 423| v423_9(void) = AliasedUse : m423_3
|
||||
# 423| v423_10(void) = ExitFunction :
|
||||
|
||||
# 427| Block 2
|
||||
# 427| r427_1(glval<unknown>) = FunctionAddress[noreturnFunc] :
|
||||
# 427| v427_2(void) = Call[noreturnFunc] : func:r427_1
|
||||
# 427| m427_3(unknown) = ^CallSideEffect : ~m423_4
|
||||
# 427| m427_4(unknown) = Chi : total:m423_4, partial:m427_3
|
||||
|
||||
# 423| Block 3
|
||||
# 423| v423_11(void) = Unreached :
|
||||
|
||||
@@ -417,3 +417,13 @@ void vla(int n1, int n2, int n3, bool b1) {
|
||||
void nested_array_designators() {
|
||||
int x[1][2] = {[0][0] = 1234, [0][1] = 5678};
|
||||
}
|
||||
|
||||
[[noreturn]] void noreturnFunc();
|
||||
|
||||
int noreturnTest(int x) {
|
||||
if (x < 10) {
|
||||
return x;
|
||||
} else {
|
||||
noreturnFunc();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1940,3 +1940,34 @@ ssa.cpp:
|
||||
# 417| v417_4(void) = ReturnVoid :
|
||||
# 417| v417_5(void) = AliasedUse : ~m?
|
||||
# 417| v417_6(void) = ExitFunction :
|
||||
|
||||
# 423| int noreturnTest(int)
|
||||
# 423| Block 0
|
||||
# 423| v423_1(void) = EnterFunction :
|
||||
# 423| mu423_2(unknown) = AliasedDefinition :
|
||||
# 423| mu423_3(unknown) = InitializeNonLocal :
|
||||
# 423| r423_4(glval<int>) = VariableAddress[x] :
|
||||
# 423| m423_5(int) = InitializeParameter[x] : &:r423_4
|
||||
# 424| r424_1(glval<int>) = VariableAddress[x] :
|
||||
# 424| r424_2(int) = Load[x] : &:r424_1, m423_5
|
||||
# 424| r424_3(int) = Constant[10] :
|
||||
# 424| r424_4(bool) = CompareLT : r424_2, r424_3
|
||||
# 424| v424_5(void) = ConditionalBranch : r424_4
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 425| Block 1
|
||||
# 425| r425_1(glval<int>) = VariableAddress[#return] :
|
||||
# 425| r425_2(glval<int>) = VariableAddress[x] :
|
||||
# 425| r425_3(int) = Load[x] : &:r425_2, m423_5
|
||||
# 425| m425_4(int) = Store[#return] : &:r425_1, r425_3
|
||||
# 423| r423_6(glval<int>) = VariableAddress[#return] :
|
||||
# 423| v423_7(void) = ReturnValue : &:r423_6, m425_4
|
||||
# 423| v423_8(void) = AliasedUse : ~m?
|
||||
# 423| v423_9(void) = ExitFunction :
|
||||
|
||||
# 427| Block 2
|
||||
# 427| r427_1(glval<unknown>) = FunctionAddress[noreturnFunc] :
|
||||
# 427| v427_2(void) = Call[noreturnFunc] : func:r427_1
|
||||
# 427| mu427_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 423| v423_10(void) = Unreached :
|
||||
|
||||
@@ -1940,3 +1940,34 @@ ssa.cpp:
|
||||
# 417| v417_4(void) = ReturnVoid :
|
||||
# 417| v417_5(void) = AliasedUse : ~m?
|
||||
# 417| v417_6(void) = ExitFunction :
|
||||
|
||||
# 423| int noreturnTest(int)
|
||||
# 423| Block 0
|
||||
# 423| v423_1(void) = EnterFunction :
|
||||
# 423| mu423_2(unknown) = AliasedDefinition :
|
||||
# 423| mu423_3(unknown) = InitializeNonLocal :
|
||||
# 423| r423_4(glval<int>) = VariableAddress[x] :
|
||||
# 423| m423_5(int) = InitializeParameter[x] : &:r423_4
|
||||
# 424| r424_1(glval<int>) = VariableAddress[x] :
|
||||
# 424| r424_2(int) = Load[x] : &:r424_1, m423_5
|
||||
# 424| r424_3(int) = Constant[10] :
|
||||
# 424| r424_4(bool) = CompareLT : r424_2, r424_3
|
||||
# 424| v424_5(void) = ConditionalBranch : r424_4
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 425| Block 1
|
||||
# 425| r425_1(glval<int>) = VariableAddress[#return] :
|
||||
# 425| r425_2(glval<int>) = VariableAddress[x] :
|
||||
# 425| r425_3(int) = Load[x] : &:r425_2, m423_5
|
||||
# 425| m425_4(int) = Store[#return] : &:r425_1, r425_3
|
||||
# 423| r423_6(glval<int>) = VariableAddress[#return] :
|
||||
# 423| v423_7(void) = ReturnValue : &:r423_6, m425_4
|
||||
# 423| v423_8(void) = AliasedUse : ~m?
|
||||
# 423| v423_9(void) = ExitFunction :
|
||||
|
||||
# 427| Block 2
|
||||
# 427| r427_1(glval<unknown>) = FunctionAddress[noreturnFunc] :
|
||||
# 427| v427_2(void) = Call[noreturnFunc] : func:r427_1
|
||||
# 427| mu427_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 423| v423_10(void) = Unreached :
|
||||
|
||||
Reference in New Issue
Block a user