Skip to content

Commit 96bd9a9

Browse files
committed
C++: Add test case for IR edge case
1 parent c2f2522 commit 96bd9a9

File tree

6 files changed

+132
-0
lines changed

6 files changed

+132
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&)
2+
#-----| <params>:
3+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
4+
#-----| Type = [LValueReferenceType] const __va_list_tag &
5+
#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&)
6+
#-----| <params>:
7+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
8+
#-----| Type = [RValueReferenceType] __va_list_tag &&
9+
#-----| [Operator,TopLevelFunction] void operator delete(void*)
10+
#-----| <params>:
11+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12+
#-----| Type = [VoidPointerType] void *
13+
test.cpp:
14+
# 5| [TopLevelFunction] void foo(int*)
15+
# 5| <params>:
16+
# 5| getParameter(0): [Parameter] x
17+
# 5| Type = [IntPointerType] int *
18+
# 5| getEntryPoint(): [BlockStmt] { ... }
19+
# 6| getStmt(0): [ExprStmt] ExprStmt
20+
# 6| getExpr(): [DeleteExpr] delete
21+
# 6| Type = [VoidType] void
22+
# 6| ValueCategory = prvalue
23+
# 6| getExprWithReuse(): [VariableAccess] x
24+
# 6| Type = [IntPointerType] int *
25+
# 6| ValueCategory = prvalue(load)
26+
# 7| getStmt(1): [ReturnStmt] return ...
27+
# 9| [TopLevelFunction] void bar()
28+
# 9| <params>:
29+
# 11| [TopLevelFunction] void jazz()
30+
# 11| <params>:
31+
# 11| getEntryPoint(): [BlockStmt] { ... }
32+
# 12| getStmt(0): [ExprStmt] ExprStmt
33+
# 12| getExpr(): [FunctionCall] call to bar
34+
# 12| Type = [VoidType] void
35+
# 12| ValueCategory = prvalue
36+
# 13| getStmt(1): [ReturnStmt] return ...
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @kind graph
3+
*/
4+
5+
private import cpp
6+
private import semmle.code.cpp.PrintAST
7+
private import PrintConfig
8+
9+
private class PrintConfig extends PrintAstConfiguration {
10+
override predicate shouldPrintDeclaration(Declaration decl) { shouldDumpDeclaration(decl) }
11+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
private import cpp
2+
3+
/**
4+
* Holds if the specified location is in standard headers.
5+
*/
6+
predicate locationIsInStandardHeaders(Location loc) {
7+
loc.getFile().getAbsolutePath().regexpMatch(".*/include/[^/]+")
8+
}
9+
10+
/**
11+
* Holds if the AST or IR for the specified declaration should be printed in the test output.
12+
*
13+
* This predicate excludes declarations defined in standard headers.
14+
*/
15+
predicate shouldDumpDeclaration(Declaration decl) {
16+
not locationIsInStandardHeaders(decl.getLocation()) and
17+
(
18+
decl instanceof Function
19+
or
20+
decl.(GlobalOrNamespaceVariable).hasInitializer()
21+
or
22+
decl.(StaticLocalVariable).hasInitializer()
23+
)
24+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
test.cpp:
2+
# 5| void foo(int*)
3+
# 5| Block 0
4+
# 5| v5_1(void) = EnterFunction :
5+
# 5| m5_2(unknown) = AliasedDefinition :
6+
# 5| m5_3(unknown) = InitializeNonLocal :
7+
# 5| m5_4(unknown) = Chi : total:m5_2, partial:m5_3
8+
# 5| r5_5(glval<int *>) = VariableAddress[x] :
9+
# 5| m5_6(int *) = InitializeParameter[x] : &:r5_5
10+
# 5| r5_7(int *) = Load[x] : &:r5_5, m5_6
11+
# 5| m5_8(unknown) = InitializeIndirection[x] : &:r5_7
12+
# 6| r6_1(glval<unknown>) = FunctionAddress[operator delete] :
13+
# 6| r6_2(glval<int *>) = VariableAddress[x] :
14+
# 6| r6_3(int *) = Load[x] : &:r6_2, m5_6
15+
# 6| v6_4(void) = Call[operator delete] : func:r6_1
16+
# 6| m6_5(unknown) = ^CallSideEffect : ~m5_4
17+
# 6| m6_6(unknown) = Chi : total:m5_4, partial:m6_5
18+
# 7| v7_1(void) = NoOp :
19+
# 5| v5_9(void) = ReturnIndirection[x] : &:r5_7, m5_8
20+
# 5| v5_10(void) = ReturnVoid :
21+
# 5| v5_11(void) = AliasedUse : ~m6_6
22+
# 5| v5_12(void) = ExitFunction :
23+
24+
# 11| void jazz()
25+
# 11| Block 0
26+
# 11| v11_1(void) = EnterFunction :
27+
# 11| m11_2(unknown) = AliasedDefinition :
28+
# 11| m11_3(unknown) = InitializeNonLocal :
29+
# 11| m11_4(unknown) = Chi : total:m11_2, partial:m11_3
30+
# 12| r12_1(glval<unknown>) = FunctionAddress[bar] :
31+
# 12| v12_2(void) = Call[bar] : func:r12_1
32+
# 12| m12_3(unknown) = ^CallSideEffect : ~m11_4
33+
# 12| m12_4(unknown) = Chi : total:m11_4, partial:m12_3
34+
# 13| v13_1(void) = NoOp :
35+
# 11| v11_5(void) = ReturnVoid :
36+
# 11| v11_6(void) = AliasedUse : ~m12_4
37+
# 11| v11_7(void) = ExitFunction :
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @kind graph
3+
*/
4+
5+
private import cpp
6+
private import semmle.code.cpp.ir.implementation.aliased_ssa.PrintIR
7+
private import PrintConfig
8+
9+
private class PrintConfig extends PrintIRConfiguration {
10+
override predicate shouldPrintDeclaration(Declaration decl) { shouldDumpDeclaration(decl) }
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Test for edge case, where we have a database without any function calls or
2+
// where none of the function calls have any arguments, but where we do have
3+
// a delete expression.
4+
5+
void foo(int* x) {
6+
delete x;
7+
}
8+
9+
void bar();
10+
11+
void jazz() {
12+
bar();
13+
}

0 commit comments

Comments
 (0)