mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
C++: Fix IR generation of return of void expression
This commit is contained in:
@@ -135,7 +135,7 @@ abstract class TranslatedReturnStmt extends TranslatedStmt {
|
||||
* The IR translation of a `return` statement that returns a value.
|
||||
*/
|
||||
class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariableInitialization {
|
||||
TranslatedReturnValueStmt() { stmt.hasExpr() }
|
||||
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
|
||||
|
||||
final override Instruction getInitializationSuccessor() {
|
||||
result = getEnclosingFunction().getReturnSuccessorInstruction()
|
||||
@@ -150,6 +150,41 @@ class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariable
|
||||
final override IRVariable getIRVariable() { result = getEnclosingFunction().getReturnVariable() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of a `return` statement that returns an expression of `void` type.
|
||||
*/
|
||||
class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
TranslatedReturnVoidExpressionStmt() {
|
||||
stmt.hasExpr() and not hasReturnValue(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
id = 0 and
|
||||
result = getExpr()
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() { result = getExpr().getFirstInstruction() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getEnclosingFunction().getReturnSuccessorInstruction() and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = getExpr() and
|
||||
result = getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of a `return` statement that does not return a value. This includes implicit
|
||||
* return statements at the end of `void`-returning functions.
|
||||
|
||||
@@ -8767,6 +8767,23 @@ ir.cpp:
|
||||
# 1291| Type = [IntType] int
|
||||
# 1291| ValueCategory = prvalue(load)
|
||||
# 1293| 1: [ReturnStmt] return ...
|
||||
# 1295| [TopLevelFunction] void returnVoid(int, int)
|
||||
# 1295| params:
|
||||
# 1295| 0: [Parameter] x
|
||||
# 1295| Type = [IntType] int
|
||||
# 1295| 1: [Parameter] y
|
||||
# 1295| Type = [IntType] int
|
||||
# 1295| body: [Block] { ... }
|
||||
# 1296| 0: [ReturnStmt] return ...
|
||||
# 1296| 0: [FunctionCall] call to IntegerOps
|
||||
# 1296| Type = [VoidType] void
|
||||
# 1296| ValueCategory = prvalue
|
||||
# 1296| 0: [VariableAccess] x
|
||||
# 1296| Type = [IntType] int
|
||||
# 1296| ValueCategory = prvalue(load)
|
||||
# 1296| 1: [VariableAccess] y
|
||||
# 1296| Type = [IntType] int
|
||||
# 1296| ValueCategory = prvalue(load)
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| params:
|
||||
|
||||
@@ -1292,4 +1292,8 @@ int missingReturnValue(bool b, int x) {
|
||||
}
|
||||
}
|
||||
|
||||
void returnVoid(int x, int y) {
|
||||
return IntegerOps(x, y);
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -6661,6 +6661,29 @@ ir.cpp:
|
||||
# 1289| v1289_12(void) = AliasedUse : ~mu1289_4
|
||||
# 1289| v1289_13(void) = ExitFunction :
|
||||
|
||||
# 1295| void returnVoid(int, int)
|
||||
# 1295| Block 0
|
||||
# 1295| v1295_1(void) = EnterFunction :
|
||||
# 1295| mu1295_2(unknown) = AliasedDefinition :
|
||||
# 1295| mu1295_3(unknown) = InitializeNonLocal :
|
||||
# 1295| mu1295_4(unknown) = UnmodeledDefinition :
|
||||
# 1295| r1295_5(glval<int>) = VariableAddress[x] :
|
||||
# 1295| mu1295_6(int) = InitializeParameter[x] : &:r1295_5
|
||||
# 1295| r1295_7(glval<int>) = VariableAddress[y] :
|
||||
# 1295| mu1295_8(int) = InitializeParameter[y] : &:r1295_7
|
||||
# 1296| r1296_1(glval<unknown>) = FunctionAddress[IntegerOps] :
|
||||
# 1296| r1296_2(glval<int>) = VariableAddress[x] :
|
||||
# 1296| r1296_3(int) = Load : &:r1296_2, ~mu1295_4
|
||||
# 1296| r1296_4(glval<int>) = VariableAddress[y] :
|
||||
# 1296| r1296_5(int) = Load : &:r1296_4, ~mu1295_4
|
||||
# 1296| v1296_6(void) = Call : func:r1296_1, 0:r1296_3, 1:r1296_5
|
||||
# 1296| mu1296_7(unknown) = ^CallSideEffect : ~mu1295_4
|
||||
# 1296| v1296_8(void) = NoOp :
|
||||
# 1295| v1295_9(void) = ReturnVoid :
|
||||
# 1295| v1295_10(void) = UnmodeledUse : mu*
|
||||
# 1295| v1295_11(void) = AliasedUse : ~mu1295_4
|
||||
# 1295| v1295_12(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
Reference in New Issue
Block a user