C++: Add test case for IR edge case

This commit is contained in:
Jeroen Ketema
2025-05-14 13:36:52 +02:00
parent c2f2522262
commit 96bd9a96e5
6 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&)
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const __va_list_tag &
#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&)
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] __va_list_tag &&
#-----| [Operator,TopLevelFunction] void operator delete(void*)
#-----| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [VoidPointerType] void *
test.cpp:
# 5| [TopLevelFunction] void foo(int*)
# 5| <params>:
# 5| getParameter(0): [Parameter] x
# 5| Type = [IntPointerType] int *
# 5| getEntryPoint(): [BlockStmt] { ... }
# 6| getStmt(0): [ExprStmt] ExprStmt
# 6| getExpr(): [DeleteExpr] delete
# 6| Type = [VoidType] void
# 6| ValueCategory = prvalue
# 6| getExprWithReuse(): [VariableAccess] x
# 6| Type = [IntPointerType] int *
# 6| ValueCategory = prvalue(load)
# 7| getStmt(1): [ReturnStmt] return ...
# 9| [TopLevelFunction] void bar()
# 9| <params>:
# 11| [TopLevelFunction] void jazz()
# 11| <params>:
# 11| getEntryPoint(): [BlockStmt] { ... }
# 12| getStmt(0): [ExprStmt] ExprStmt
# 12| getExpr(): [FunctionCall] call to bar
# 12| Type = [VoidType] void
# 12| ValueCategory = prvalue
# 13| getStmt(1): [ReturnStmt] return ...

View File

@@ -0,0 +1,11 @@
/**
* @kind graph
*/
private import cpp
private import semmle.code.cpp.PrintAST
private import PrintConfig
private class PrintConfig extends PrintAstConfiguration {
override predicate shouldPrintDeclaration(Declaration decl) { shouldDumpDeclaration(decl) }
}

View File

@@ -0,0 +1,24 @@
private import cpp
/**
* Holds if the specified location is in standard headers.
*/
predicate locationIsInStandardHeaders(Location loc) {
loc.getFile().getAbsolutePath().regexpMatch(".*/include/[^/]+")
}
/**
* Holds if the AST or IR for the specified declaration should be printed in the test output.
*
* This predicate excludes declarations defined in standard headers.
*/
predicate shouldDumpDeclaration(Declaration decl) {
not locationIsInStandardHeaders(decl.getLocation()) and
(
decl instanceof Function
or
decl.(GlobalOrNamespaceVariable).hasInitializer()
or
decl.(StaticLocalVariable).hasInitializer()
)
}

View File

@@ -0,0 +1,37 @@
test.cpp:
# 5| void foo(int*)
# 5| Block 0
# 5| v5_1(void) = EnterFunction :
# 5| m5_2(unknown) = AliasedDefinition :
# 5| m5_3(unknown) = InitializeNonLocal :
# 5| m5_4(unknown) = Chi : total:m5_2, partial:m5_3
# 5| r5_5(glval<int *>) = VariableAddress[x] :
# 5| m5_6(int *) = InitializeParameter[x] : &:r5_5
# 5| r5_7(int *) = Load[x] : &:r5_5, m5_6
# 5| m5_8(unknown) = InitializeIndirection[x] : &:r5_7
# 6| r6_1(glval<unknown>) = FunctionAddress[operator delete] :
# 6| r6_2(glval<int *>) = VariableAddress[x] :
# 6| r6_3(int *) = Load[x] : &:r6_2, m5_6
# 6| v6_4(void) = Call[operator delete] : func:r6_1
# 6| m6_5(unknown) = ^CallSideEffect : ~m5_4
# 6| m6_6(unknown) = Chi : total:m5_4, partial:m6_5
# 7| v7_1(void) = NoOp :
# 5| v5_9(void) = ReturnIndirection[x] : &:r5_7, m5_8
# 5| v5_10(void) = ReturnVoid :
# 5| v5_11(void) = AliasedUse : ~m6_6
# 5| v5_12(void) = ExitFunction :
# 11| void jazz()
# 11| Block 0
# 11| v11_1(void) = EnterFunction :
# 11| m11_2(unknown) = AliasedDefinition :
# 11| m11_3(unknown) = InitializeNonLocal :
# 11| m11_4(unknown) = Chi : total:m11_2, partial:m11_3
# 12| r12_1(glval<unknown>) = FunctionAddress[bar] :
# 12| v12_2(void) = Call[bar] : func:r12_1
# 12| m12_3(unknown) = ^CallSideEffect : ~m11_4
# 12| m12_4(unknown) = Chi : total:m11_4, partial:m12_3
# 13| v13_1(void) = NoOp :
# 11| v11_5(void) = ReturnVoid :
# 11| v11_6(void) = AliasedUse : ~m12_4
# 11| v11_7(void) = ExitFunction :

View File

@@ -0,0 +1,11 @@
/**
* @kind graph
*/
private import cpp
private import semmle.code.cpp.ir.implementation.aliased_ssa.PrintIR
private import PrintConfig
private class PrintConfig extends PrintIRConfiguration {
override predicate shouldPrintDeclaration(Declaration decl) { shouldDumpDeclaration(decl) }
}

View File

@@ -0,0 +1,13 @@
// Test for edge case, where we have a database without any function calls or
// where none of the function calls have any arguments, but where we do have
// a delete expression.
void foo(int* x) {
delete x;
}
void bar();
void jazz() {
bar();
}