Skip to content

Commit e4e0d3b

Browse files
committed
C++: Add test cases showing that static member function calls get 'this' pointers and side effects for 'this' when accessed through qualifiers
1 parent 42e9d14 commit e4e0d3b

File tree

3 files changed

+398
-0
lines changed

3 files changed

+398
-0
lines changed

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4048,6 +4048,27 @@ ir.cpp:
40484048
#-----| Type = [RValueReferenceType] C &&
40494049
# 628| [Destructor] void C::~C()
40504050
# 628| params:
4051+
#-----| body: [Block] { ... }
4052+
#-----| 0: [ReturnStmt] return ...
4053+
# 628| destructions:
4054+
# 628| 0: [DestructorFieldDestruction] destructor field destruction of m_f
4055+
# 628| Type = [Struct] String
4056+
# 628| ValueCategory = prvalue
4057+
# 628| 0: [DestructorCall] call to ~String
4058+
# 628| Type = [VoidType] void
4059+
# 628| ValueCategory = prvalue
4060+
# 628| -1: [ImplicitThisFieldAccess] m_f
4061+
# 628| Type = [Struct] String
4062+
# 628| ValueCategory = lvalue
4063+
# 628| 1: [DestructorFieldDestruction] destructor field destruction of m_b
4064+
# 628| Type = [Struct] String
4065+
# 628| ValueCategory = prvalue
4066+
# 628| 0: [DestructorCall] call to ~String
4067+
# 628| Type = [VoidType] void
4068+
# 628| ValueCategory = prvalue
4069+
# 628| -1: [ImplicitThisFieldAccess] m_b
4070+
# 628| Type = [Struct] String
4071+
# 628| ValueCategory = lvalue
40514072
# 630| [MemberFunction] int C::StaticMemberFunction(int)
40524073
# 630| params:
40534074
# 630| 0: [Parameter] x
@@ -8545,6 +8566,190 @@ ir.cpp:
85458566
# 1255| Type = [CharPointerType] char *
85468567
# 1255| ValueCategory = prvalue(load)
85478568
# 1256| 3: [ReturnStmt] return ...
8569+
# 1258| [CopyAssignmentOperator] A& A::operator=(A const&)
8570+
# 1258| params:
8571+
#-----| 0: [Parameter] p#0
8572+
#-----| Type = [LValueReferenceType] const A &
8573+
# 1258| [MoveAssignmentOperator] A& A::operator=(A&&)
8574+
# 1258| params:
8575+
#-----| 0: [Parameter] p#0
8576+
#-----| Type = [RValueReferenceType] A &&
8577+
# 1261| [MemberFunction] void A::static_member(A*, int)
8578+
# 1261| params:
8579+
# 1261| 0: [Parameter] a
8580+
# 1261| Type = [PointerType] A *
8581+
# 1261| 1: [Parameter] x
8582+
# 1261| Type = [IntType] int
8583+
# 1261| body: [Block] { ... }
8584+
# 1262| 0: [ExprStmt] ExprStmt
8585+
# 1262| 0: [AssignExpr] ... = ...
8586+
# 1262| Type = [IntType] int
8587+
# 1262| ValueCategory = lvalue
8588+
# 1262| 0: [PointerFieldAccess] member
8589+
# 1262| Type = [IntType] int
8590+
# 1262| ValueCategory = lvalue
8591+
# 1262| -1: [VariableAccess] a
8592+
# 1262| Type = [PointerType] A *
8593+
# 1262| ValueCategory = prvalue(load)
8594+
# 1262| 1: [VariableAccess] x
8595+
# 1262| Type = [IntType] int
8596+
# 1262| ValueCategory = prvalue(load)
8597+
# 1263| 1: [ReturnStmt] return ...
8598+
# 1265| [MemberFunction] void A::static_member_without_def()
8599+
# 1265| params:
8600+
# 1268| [TopLevelFunction] A* getAnInstanceOfA()
8601+
# 1268| params:
8602+
# 1270| [TopLevelFunction] void test_static_member_functions(int, A*)
8603+
# 1270| params:
8604+
# 1270| 0: [Parameter] int_arg
8605+
# 1270| Type = [IntType] int
8606+
# 1270| 1: [Parameter] a_arg
8607+
# 1270| Type = [PointerType] A *
8608+
# 1270| body: [Block] { ... }
8609+
# 1271| 0: [DeclStmt] declaration
8610+
# 1271| 0: [VariableDeclarationEntry] definition of c
8611+
# 1271| Type = [Class] C
8612+
# 1271| init: [Initializer] initializer for c
8613+
# 1271| expr: [ConstructorCall] call to C
8614+
# 1271| Type = [VoidType] void
8615+
# 1271| ValueCategory = prvalue
8616+
# 1272| 1: [ExprStmt] ExprStmt
8617+
# 1272| 0: [FunctionCall] call to StaticMemberFunction
8618+
# 1272| Type = [IntType] int
8619+
# 1272| ValueCategory = prvalue
8620+
# 1272| -1: [VariableAccess] c
8621+
# 1272| Type = [Class] C
8622+
# 1272| ValueCategory = lvalue
8623+
# 1272| 0: [Literal] 10
8624+
# 1272| Type = [IntType] int
8625+
# 1272| Value = [Literal] 10
8626+
# 1272| ValueCategory = prvalue
8627+
# 1273| 2: [ExprStmt] ExprStmt
8628+
# 1273| 0: [FunctionCall] call to StaticMemberFunction
8629+
# 1273| Type = [IntType] int
8630+
# 1273| ValueCategory = prvalue
8631+
# 1273| 0: [Literal] 10
8632+
# 1273| Type = [IntType] int
8633+
# 1273| Value = [Literal] 10
8634+
# 1273| ValueCategory = prvalue
8635+
# 1275| 3: [DeclStmt] declaration
8636+
# 1275| 0: [VariableDeclarationEntry] definition of a
8637+
# 1275| Type = [Struct] A
8638+
# 1276| 4: [ExprStmt] ExprStmt
8639+
# 1276| 0: [FunctionCall] call to static_member
8640+
# 1276| Type = [VoidType] void
8641+
# 1276| ValueCategory = prvalue
8642+
# 1276| -1: [VariableAccess] a
8643+
# 1276| Type = [Struct] A
8644+
# 1276| ValueCategory = lvalue
8645+
# 1276| 0: [AddressOfExpr] & ...
8646+
# 1276| Type = [PointerType] A *
8647+
# 1276| ValueCategory = prvalue
8648+
# 1276| 0: [VariableAccess] a
8649+
# 1276| Type = [Struct] A
8650+
# 1276| ValueCategory = lvalue
8651+
# 1276| 1: [VariableAccess] int_arg
8652+
# 1276| Type = [IntType] int
8653+
# 1276| ValueCategory = prvalue(load)
8654+
# 1277| 5: [ExprStmt] ExprStmt
8655+
# 1277| 0: [FunctionCall] call to static_member
8656+
# 1277| Type = [VoidType] void
8657+
# 1277| ValueCategory = prvalue
8658+
# 1277| 0: [AddressOfExpr] & ...
8659+
# 1277| Type = [PointerType] A *
8660+
# 1277| ValueCategory = prvalue
8661+
# 1277| 0: [VariableAccess] a
8662+
# 1277| Type = [Struct] A
8663+
# 1277| ValueCategory = lvalue
8664+
# 1277| 1: [VariableAccess] int_arg
8665+
# 1277| Type = [IntType] int
8666+
# 1277| ValueCategory = prvalue(load)
8667+
# 1279| 6: [ExprStmt] ExprStmt
8668+
# 1279| 0: [FunctionCall] call to static_member
8669+
# 1279| Type = [VoidType] void
8670+
# 1279| ValueCategory = prvalue
8671+
# 1279| -1: [ParenthesisExpr] (...)
8672+
# 1279| Type = [PointerType] A *
8673+
# 1279| ValueCategory = prvalue
8674+
# 1279| expr: [AddressOfExpr] & ...
8675+
# 1279| Type = [PointerType] A *
8676+
# 1279| ValueCategory = prvalue
8677+
# 1279| 0: [VariableAccess] a
8678+
# 1279| Type = [Struct] A
8679+
# 1279| ValueCategory = lvalue
8680+
# 1279| 0: [VariableAccess] a_arg
8681+
# 1279| Type = [PointerType] A *
8682+
# 1279| ValueCategory = prvalue(load)
8683+
# 1279| 1: [AddExpr] ... + ...
8684+
# 1279| Type = [IntType] int
8685+
# 1279| ValueCategory = prvalue
8686+
# 1279| 0: [VariableAccess] int_arg
8687+
# 1279| Type = [IntType] int
8688+
# 1279| ValueCategory = prvalue(load)
8689+
# 1279| 1: [Literal] 2
8690+
# 1279| Type = [IntType] int
8691+
# 1279| Value = [Literal] 2
8692+
# 1279| ValueCategory = prvalue
8693+
# 1280| 7: [ExprStmt] ExprStmt
8694+
# 1280| 0: [FunctionCall] call to static_member
8695+
# 1280| Type = [VoidType] void
8696+
# 1280| ValueCategory = prvalue
8697+
# 1280| -1: [ParenthesisExpr] (...)
8698+
# 1280| Type = [Struct] A
8699+
# 1280| ValueCategory = lvalue
8700+
# 1280| expr: [PointerDereferenceExpr] * ...
8701+
# 1280| Type = [Struct] A
8702+
# 1280| ValueCategory = lvalue
8703+
# 1280| 0: [VariableAccess] a_arg
8704+
# 1280| Type = [PointerType] A *
8705+
# 1280| ValueCategory = prvalue(load)
8706+
# 1280| 0: [AddressOfExpr] & ...
8707+
# 1280| Type = [PointerType] A *
8708+
# 1280| ValueCategory = prvalue
8709+
# 1280| 0: [VariableAccess] a
8710+
# 1280| Type = [Struct] A
8711+
# 1280| ValueCategory = lvalue
8712+
# 1280| 1: [Literal] 99
8713+
# 1280| Type = [IntType] int
8714+
# 1280| Value = [Literal] 99
8715+
# 1280| ValueCategory = prvalue
8716+
# 1281| 8: [ExprStmt] ExprStmt
8717+
# 1281| 0: [FunctionCall] call to static_member
8718+
# 1281| Type = [VoidType] void
8719+
# 1281| ValueCategory = prvalue
8720+
# 1281| -1: [VariableAccess] a_arg
8721+
# 1281| Type = [PointerType] A *
8722+
# 1281| ValueCategory = prvalue(load)
8723+
# 1281| 0: [VariableAccess] a_arg
8724+
# 1281| Type = [PointerType] A *
8725+
# 1281| ValueCategory = prvalue(load)
8726+
# 1281| 1: [UnaryMinusExpr] - ...
8727+
# 1281| Type = [IntType] int
8728+
# 1281| Value = [UnaryMinusExpr] -1
8729+
# 1281| ValueCategory = prvalue
8730+
# 1281| 0: [Literal] 1
8731+
# 1281| Type = [IntType] int
8732+
# 1281| Value = [Literal] 1
8733+
# 1281| ValueCategory = prvalue
8734+
# 1283| 9: [ExprStmt] ExprStmt
8735+
# 1283| 0: [FunctionCall] call to static_member_without_def
8736+
# 1283| Type = [VoidType] void
8737+
# 1283| ValueCategory = prvalue
8738+
# 1283| -1: [VariableAccess] a
8739+
# 1283| Type = [Struct] A
8740+
# 1283| ValueCategory = lvalue
8741+
# 1284| 10: [ExprStmt] ExprStmt
8742+
# 1284| 0: [FunctionCall] call to static_member_without_def
8743+
# 1284| Type = [VoidType] void
8744+
# 1284| ValueCategory = prvalue
8745+
# 1286| 11: [ExprStmt] ExprStmt
8746+
# 1286| 0: [FunctionCall] call to static_member_without_def
8747+
# 1286| Type = [VoidType] void
8748+
# 1286| ValueCategory = prvalue
8749+
# 1286| -1: [FunctionCall] call to getAnInstanceOfA
8750+
# 1286| Type = [PointerType] A *
8751+
# 1286| ValueCategory = prvalue
8752+
# 1287| 12: [ReturnStmt] return ...
85488753
perf-regression.cpp:
85498754
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
85508755
# 4| params:

cpp/ql/test/library-tests/ir/ir/ir.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,4 +1255,35 @@ void test_strings(char *s1, char *s2) {
12551255
strcat(buffer, s2);
12561256
}
12571257

1258+
struct A {
1259+
int member;
1260+
1261+
static void static_member(A* a, int x) {
1262+
a->member = x;
1263+
}
1264+
1265+
static void static_member_without_def();
1266+
};
1267+
1268+
A* getAnInstanceOfA();
1269+
1270+
void test_static_member_functions(int int_arg, A* a_arg) {
1271+
C c;
1272+
c.StaticMemberFunction(10);
1273+
C::StaticMemberFunction(10);
1274+
1275+
A a;
1276+
a.static_member(&a, int_arg);
1277+
A::static_member(&a, int_arg);
1278+
1279+
(&a)->static_member(a_arg, int_arg + 2);
1280+
(*a_arg).static_member(&a, 99);
1281+
a_arg->static_member(a_arg, -1);
1282+
1283+
a.static_member_without_def();
1284+
A::static_member_without_def();
1285+
1286+
getAnInstanceOfA()->static_member_without_def();
1287+
}
1288+
12581289
// semmle-extractor-options: -std=c++17 --clang

0 commit comments

Comments
 (0)