C++: Add more IR tests

These show the value categories for more static member calls, and show that
a load occurs when a `volatile` variable is being used in an empty context.
This commit is contained in:
Jeroen Ketema
2023-07-18 08:40:54 +02:00
parent e6d7a83d41
commit e2de94b233
4 changed files with 349 additions and 0 deletions

View File

@@ -14596,6 +14596,141 @@ ir.cpp:
# 1935| Type = [IntType] int
# 1935| ValueCategory = prvalue
# 1936| getStmt(2): [ReturnStmt] return ...
# 1938| [CopyAssignmentOperator] D& D::operator=(D const&)
# 1938| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const D &
# 1938| [MoveAssignmentOperator] D& D::operator=(D&&)
# 1938| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] D &&
# 1942| [MemberFunction] D& D::ReferenceStaticMemberFunction()
# 1942| <params>:
# 1942| getEntryPoint(): [BlockStmt] { ... }
# 1943| getStmt(0): [ReturnStmt] return ...
# 1943| getExpr(): [VariableAccess] x
# 1943| Type = [Class] D
# 1943| ValueCategory = lvalue
# 1943| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
# 1943| Type = [LValueReferenceType] D &
# 1943| ValueCategory = prvalue
# 1945| [MemberFunction] D D::ObjectStaticMemberFunction()
# 1945| <params>:
# 1945| getEntryPoint(): [BlockStmt] { ... }
# 1946| getStmt(0): [ReturnStmt] return ...
# 1946| getExpr(): [VariableAccess] x
# 1946| Type = [Class] D
# 1946| ValueCategory = prvalue(load)
# 1950| [TopLevelFunction] void test_static_member_functions_with_reference_return()
# 1950| <params>:
# 1950| getEntryPoint(): [BlockStmt] { ... }
# 1951| getStmt(0): [DeclStmt] declaration
# 1951| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
# 1951| Type = [Class] D
# 1953| getStmt(1): [ExprStmt] ExprStmt
# 1953| getExpr(): [FunctionCall] call to ReferenceStaticMemberFunction
# 1953| Type = [LValueReferenceType] D &
# 1953| ValueCategory = prvalue
# 1953| getQualifier(): [VariableAccess] d
# 1953| Type = [Class] D
# 1953| ValueCategory = lvalue
# 1953| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1953| Type = [Class] D
# 1953| ValueCategory = lvalue
# 1954| getStmt(2): [ExprStmt] ExprStmt
# 1954| getExpr(): [FunctionCall] call to ReferenceStaticMemberFunction
# 1954| Type = [LValueReferenceType] D &
# 1954| ValueCategory = prvalue
# 1954| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1954| Type = [Class] D
# 1954| ValueCategory = lvalue
# 1955| getStmt(3): [ExprStmt] ExprStmt
# 1955| getExpr(): [FunctionCall] call to ObjectStaticMemberFunction
# 1955| Type = [Class] D
# 1955| ValueCategory = prvalue
# 1955| getQualifier(): [VariableAccess] d
# 1955| Type = [Class] D
# 1955| ValueCategory = lvalue
# 1956| getStmt(4): [ExprStmt] ExprStmt
# 1956| getExpr(): [FunctionCall] call to ObjectStaticMemberFunction
# 1956| Type = [Class] D
# 1956| ValueCategory = prvalue
# 1958| getStmt(5): [DeclStmt] declaration
# 1958| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
# 1958| Type = [Class] D
# 1959| getStmt(6): [ExprStmt] ExprStmt
# 1959| getExpr(): [AssignExpr] ... = ...
# 1959| Type = [Class] D
# 1959| ValueCategory = lvalue
# 1959| getLValue(): [VariableAccess] x
# 1959| Type = [Class] D
# 1959| ValueCategory = lvalue
# 1959| getRValue(): [FunctionCall] call to ReferenceStaticMemberFunction
# 1959| Type = [LValueReferenceType] D &
# 1959| ValueCategory = prvalue
# 1959| getQualifier(): [VariableAccess] d
# 1959| Type = [Class] D
# 1959| ValueCategory = lvalue
# 1959| getRValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1959| Type = [Class] D
# 1959| ValueCategory = prvalue(load)
# 1960| getStmt(7): [DeclStmt] declaration
# 1960| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 1960| Type = [Class] D
# 1961| getStmt(8): [ExprStmt] ExprStmt
# 1961| getExpr(): [AssignExpr] ... = ...
# 1961| Type = [Class] D
# 1961| ValueCategory = lvalue
# 1961| getLValue(): [VariableAccess] y
# 1961| Type = [Class] D
# 1961| ValueCategory = lvalue
# 1961| getRValue(): [FunctionCall] call to ReferenceStaticMemberFunction
# 1961| Type = [LValueReferenceType] D &
# 1961| ValueCategory = prvalue
# 1961| getRValue().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1961| Type = [Class] D
# 1961| ValueCategory = prvalue(load)
# 1962| getStmt(9): [DeclStmt] declaration
# 1962| getDeclarationEntry(0): [VariableDeclarationEntry] definition of j
# 1962| Type = [Class] D
# 1963| getStmt(10): [ExprStmt] ExprStmt
# 1963| getExpr(): [AssignExpr] ... = ...
# 1963| Type = [Class] D
# 1963| ValueCategory = lvalue
# 1963| getLValue(): [VariableAccess] j
# 1963| Type = [Class] D
# 1963| ValueCategory = lvalue
# 1963| getRValue(): [FunctionCall] call to ObjectStaticMemberFunction
# 1963| Type = [Class] D
# 1963| ValueCategory = prvalue
# 1963| getQualifier(): [VariableAccess] d
# 1963| Type = [Class] D
# 1963| ValueCategory = lvalue
# 1964| getStmt(11): [DeclStmt] declaration
# 1964| getDeclarationEntry(0): [VariableDeclarationEntry] definition of k
# 1964| Type = [Class] D
# 1965| getStmt(12): [ExprStmt] ExprStmt
# 1965| getExpr(): [AssignExpr] ... = ...
# 1965| Type = [Class] D
# 1965| ValueCategory = lvalue
# 1965| getLValue(): [VariableAccess] k
# 1965| Type = [Class] D
# 1965| ValueCategory = lvalue
# 1965| getRValue(): [FunctionCall] call to ObjectStaticMemberFunction
# 1965| Type = [Class] D
# 1965| ValueCategory = prvalue
# 1966| getStmt(13): [ReturnStmt] return ...
# 1968| [TopLevelFunction] void test_volatile()
# 1968| <params>:
# 1968| getEntryPoint(): [BlockStmt] { ... }
# 1969| getStmt(0): [DeclStmt] declaration
# 1969| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
# 1969| Type = [SpecifiedType] volatile int
# 1970| getStmt(1): [ExprStmt] ExprStmt
# 1970| getExpr(): [VariableAccess] x
# 1970| Type = [IntType] int
# 1970| ValueCategory = prvalue(load)
# 1971| getStmt(2): [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| <params>:

View File

@@ -1935,4 +1935,39 @@ void test_assign_with_assign_operation() {
i = (j += 40);
}
class D {
static D x;
public:
static D& ReferenceStaticMemberFunction() {
return x;
}
static D ObjectStaticMemberFunction() {
return x;
}
};
void test_static_member_functions_with_reference_return() {
D d;
d.ReferenceStaticMemberFunction();
D::ReferenceStaticMemberFunction();
d.ObjectStaticMemberFunction();
D::ObjectStaticMemberFunction();
D x;
x = d.ReferenceStaticMemberFunction();
D y;
y = D::ReferenceStaticMemberFunction();
D j;
j = d.ObjectStaticMemberFunction();
D k;
k = D::ObjectStaticMemberFunction();
}
void test_volatile() {
volatile int x;
x;
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -8891,6 +8891,83 @@
| ir.cpp:1935:8:1935:14 | StoreValue | r1935_4 |
| ir.cpp:1935:8:1935:14 | StoreValue | r1935_4 |
| ir.cpp:1935:13:1935:14 | Right | r1935_1 |
| ir.cpp:1942:15:1942:43 | Address | &:r1942_5 |
| ir.cpp:1942:15:1942:43 | ChiPartial | partial:m1942_3 |
| ir.cpp:1942:15:1942:43 | ChiTotal | total:m1942_2 |
| ir.cpp:1942:15:1942:43 | Load | m1943_4 |
| ir.cpp:1942:15:1942:43 | SideEffect | m1942_3 |
| ir.cpp:1943:9:1943:17 | Address | &:r1943_1 |
| ir.cpp:1943:16:1943:16 | StoreValue | r1943_3 |
| ir.cpp:1943:16:1943:16 | Unary | r1943_2 |
| ir.cpp:1945:14:1945:39 | Address | &:r1945_5 |
| ir.cpp:1945:14:1945:39 | ChiPartial | partial:m1945_3 |
| ir.cpp:1945:14:1945:39 | ChiTotal | total:m1945_2 |
| ir.cpp:1945:14:1945:39 | Load | m1946_4 |
| ir.cpp:1945:14:1945:39 | SideEffect | m1945_3 |
| ir.cpp:1946:9:1946:17 | Address | &:r1946_1 |
| ir.cpp:1946:16:1946:16 | Address | &:r1946_2 |
| ir.cpp:1946:16:1946:16 | Load | ~m1945_3 |
| ir.cpp:1946:16:1946:16 | StoreValue | r1946_3 |
| ir.cpp:1950:6:1950:55 | ChiPartial | partial:m1950_3 |
| ir.cpp:1950:6:1950:55 | ChiTotal | total:m1950_2 |
| ir.cpp:1950:6:1950:55 | SideEffect | ~m1965_4 |
| ir.cpp:1951:7:1951:7 | Address | &:r1951_1 |
| ir.cpp:1953:7:1953:35 | CallTarget | func:r1953_2 |
| ir.cpp:1953:7:1953:35 | ChiPartial | partial:m1953_4 |
| ir.cpp:1953:7:1953:35 | ChiTotal | total:m1950_4 |
| ir.cpp:1953:7:1953:35 | SideEffect | ~m1950_4 |
| ir.cpp:1953:7:1953:35 | Unary | r1953_3 |
| ir.cpp:1954:5:1954:36 | CallTarget | func:r1954_1 |
| ir.cpp:1954:5:1954:36 | ChiPartial | partial:m1954_3 |
| ir.cpp:1954:5:1954:36 | ChiTotal | total:m1953_5 |
| ir.cpp:1954:5:1954:36 | SideEffect | ~m1953_5 |
| ir.cpp:1954:5:1954:36 | Unary | r1954_2 |
| ir.cpp:1955:7:1955:32 | CallTarget | func:r1955_2 |
| ir.cpp:1955:7:1955:32 | ChiPartial | partial:m1955_4 |
| ir.cpp:1955:7:1955:32 | ChiTotal | total:m1954_4 |
| ir.cpp:1955:7:1955:32 | SideEffect | ~m1954_4 |
| ir.cpp:1956:5:1956:33 | CallTarget | func:r1956_1 |
| ir.cpp:1956:5:1956:33 | ChiPartial | partial:m1956_3 |
| ir.cpp:1956:5:1956:33 | ChiTotal | total:m1955_5 |
| ir.cpp:1956:5:1956:33 | SideEffect | ~m1955_5 |
| ir.cpp:1958:7:1958:7 | Address | &:r1958_1 |
| ir.cpp:1959:5:1959:5 | Address | &:r1959_7 |
| ir.cpp:1959:11:1959:39 | Address | &:r1959_3 |
| ir.cpp:1959:11:1959:39 | CallTarget | func:r1959_2 |
| ir.cpp:1959:11:1959:39 | ChiPartial | partial:m1959_4 |
| ir.cpp:1959:11:1959:39 | ChiTotal | total:m1956_4 |
| ir.cpp:1959:11:1959:39 | SideEffect | ~m1956_4 |
| ir.cpp:1959:40:1959:42 | Load | ~m1959_5 |
| ir.cpp:1959:40:1959:42 | StoreValue | r1959_6 |
| ir.cpp:1960:7:1960:7 | Address | &:r1960_1 |
| ir.cpp:1961:5:1961:5 | Address | &:r1961_6 |
| ir.cpp:1961:9:1961:40 | Address | &:r1961_2 |
| ir.cpp:1961:9:1961:40 | CallTarget | func:r1961_1 |
| ir.cpp:1961:9:1961:40 | ChiPartial | partial:m1961_3 |
| ir.cpp:1961:9:1961:40 | ChiTotal | total:m1959_5 |
| ir.cpp:1961:9:1961:40 | SideEffect | ~m1959_5 |
| ir.cpp:1961:41:1961:43 | Load | ~m1961_4 |
| ir.cpp:1961:41:1961:43 | StoreValue | r1961_5 |
| ir.cpp:1962:7:1962:7 | Address | &:r1962_1 |
| ir.cpp:1963:5:1963:5 | Address | &:r1963_6 |
| ir.cpp:1963:11:1963:36 | CallTarget | func:r1963_2 |
| ir.cpp:1963:11:1963:36 | ChiPartial | partial:m1963_4 |
| ir.cpp:1963:11:1963:36 | ChiTotal | total:m1961_4 |
| ir.cpp:1963:11:1963:36 | SideEffect | ~m1961_4 |
| ir.cpp:1963:11:1963:36 | StoreValue | r1963_3 |
| ir.cpp:1964:7:1964:7 | Address | &:r1964_1 |
| ir.cpp:1965:5:1965:5 | Address | &:r1965_5 |
| ir.cpp:1965:9:1965:37 | CallTarget | func:r1965_1 |
| ir.cpp:1965:9:1965:37 | ChiPartial | partial:m1965_3 |
| ir.cpp:1965:9:1965:37 | ChiTotal | total:m1963_5 |
| ir.cpp:1965:9:1965:37 | SideEffect | ~m1963_5 |
| ir.cpp:1965:9:1965:37 | StoreValue | r1965_2 |
| ir.cpp:1968:6:1968:18 | ChiPartial | partial:m1968_3 |
| ir.cpp:1968:6:1968:18 | ChiTotal | total:m1968_2 |
| ir.cpp:1968:6:1968:18 | SideEffect | m1968_3 |
| ir.cpp:1969:18:1969:18 | Address | &:r1969_1 |
| ir.cpp:1970:5:1970:5 | Address | &:r1970_1 |
| ir.cpp:1970:5:1970:5 | Load | m1969_2 |
| 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 |

View File

@@ -10266,6 +10266,108 @@ ir.cpp:
# 1933| v1933_5(void) = AliasedUse : ~m?
# 1933| v1933_6(void) = ExitFunction :
# 1942| D& D::ReferenceStaticMemberFunction()
# 1942| Block 0
# 1942| v1942_1(void) = EnterFunction :
# 1942| mu1942_2(unknown) = AliasedDefinition :
# 1942| mu1942_3(unknown) = InitializeNonLocal :
# 1943| r1943_1(glval<D &>) = VariableAddress[#return] :
# 1943| r1943_2(glval<D>) = VariableAddress[x] :
# 1943| r1943_3(D &) = CopyValue : r1943_2
# 1943| mu1943_4(D &) = Store[#return] : &:r1943_1, r1943_3
# 1942| r1942_4(glval<D &>) = VariableAddress[#return] :
# 1942| v1942_5(void) = ReturnValue : &:r1942_4, ~m?
# 1942| v1942_6(void) = AliasedUse : ~m?
# 1942| v1942_7(void) = ExitFunction :
# 1945| D D::ObjectStaticMemberFunction()
# 1945| Block 0
# 1945| v1945_1(void) = EnterFunction :
# 1945| mu1945_2(unknown) = AliasedDefinition :
# 1945| mu1945_3(unknown) = InitializeNonLocal :
# 1946| r1946_1(glval<D>) = VariableAddress[#return] :
# 1946| r1946_2(glval<D>) = VariableAddress[x] :
# 1946| r1946_3(D) = Load[x] : &:r1946_2, ~m?
# 1946| mu1946_4(D) = Store[#return] : &:r1946_1, r1946_3
# 1945| r1945_4(glval<D>) = VariableAddress[#return] :
# 1945| v1945_5(void) = ReturnValue : &:r1945_4, ~m?
# 1945| v1945_6(void) = AliasedUse : ~m?
# 1945| v1945_7(void) = ExitFunction :
# 1950| void test_static_member_functions_with_reference_return()
# 1950| Block 0
# 1950| v1950_1(void) = EnterFunction :
# 1950| mu1950_2(unknown) = AliasedDefinition :
# 1950| mu1950_3(unknown) = InitializeNonLocal :
# 1951| r1951_1(glval<D>) = VariableAddress[d] :
# 1951| mu1951_2(D) = Uninitialized[d] : &:r1951_1
# 1953| r1953_1(glval<D>) = VariableAddress[d] :
# 1953| r1953_2(glval<unknown>) = FunctionAddress[ReferenceStaticMemberFunction] :
# 1953| r1953_3(D &) = Call[ReferenceStaticMemberFunction] : func:r1953_2
# 1953| mu1953_4(unknown) = ^CallSideEffect : ~m?
# 1953| r1953_5(glval<D>) = CopyValue : r1953_3
# 1954| r1954_1(glval<unknown>) = FunctionAddress[ReferenceStaticMemberFunction] :
# 1954| r1954_2(D &) = Call[ReferenceStaticMemberFunction] : func:r1954_1
# 1954| mu1954_3(unknown) = ^CallSideEffect : ~m?
# 1954| r1954_4(glval<D>) = CopyValue : r1954_2
# 1955| r1955_1(glval<D>) = VariableAddress[d] :
# 1955| r1955_2(glval<unknown>) = FunctionAddress[ObjectStaticMemberFunction] :
# 1955| r1955_3(D) = Call[ObjectStaticMemberFunction] : func:r1955_2
# 1955| mu1955_4(unknown) = ^CallSideEffect : ~m?
# 1956| r1956_1(glval<unknown>) = FunctionAddress[ObjectStaticMemberFunction] :
# 1956| r1956_2(D) = Call[ObjectStaticMemberFunction] : func:r1956_1
# 1956| mu1956_3(unknown) = ^CallSideEffect : ~m?
# 1958| r1958_1(glval<D>) = VariableAddress[x] :
# 1958| mu1958_2(D) = Uninitialized[x] : &:r1958_1
# 1959| r1959_1(glval<D>) = VariableAddress[d] :
# 1959| r1959_2(glval<unknown>) = FunctionAddress[ReferenceStaticMemberFunction] :
# 1959| r1959_3(D &) = Call[ReferenceStaticMemberFunction] : func:r1959_2
# 1959| mu1959_4(unknown) = ^CallSideEffect : ~m?
# 1959| r1959_5(D) = Load[?] : &:r1959_3, ~m?
# 1959| r1959_6(glval<D>) = VariableAddress[x] :
# 1959| mu1959_7(D) = Store[x] : &:r1959_6, r1959_5
# 1960| r1960_1(glval<D>) = VariableAddress[y] :
# 1960| mu1960_2(D) = Uninitialized[y] : &:r1960_1
# 1961| r1961_1(glval<unknown>) = FunctionAddress[ReferenceStaticMemberFunction] :
# 1961| r1961_2(D &) = Call[ReferenceStaticMemberFunction] : func:r1961_1
# 1961| mu1961_3(unknown) = ^CallSideEffect : ~m?
# 1961| r1961_4(D) = Load[?] : &:r1961_2, ~m?
# 1961| r1961_5(glval<D>) = VariableAddress[y] :
# 1961| mu1961_6(D) = Store[y] : &:r1961_5, r1961_4
# 1962| r1962_1(glval<D>) = VariableAddress[j] :
# 1962| mu1962_2(D) = Uninitialized[j] : &:r1962_1
# 1963| r1963_1(glval<D>) = VariableAddress[d] :
# 1963| r1963_2(glval<unknown>) = FunctionAddress[ObjectStaticMemberFunction] :
# 1963| r1963_3(D) = Call[ObjectStaticMemberFunction] : func:r1963_2
# 1963| mu1963_4(unknown) = ^CallSideEffect : ~m?
# 1963| r1963_5(glval<D>) = VariableAddress[j] :
# 1963| mu1963_6(D) = Store[j] : &:r1963_5, r1963_3
# 1964| r1964_1(glval<D>) = VariableAddress[k] :
# 1964| mu1964_2(D) = Uninitialized[k] : &:r1964_1
# 1965| r1965_1(glval<unknown>) = FunctionAddress[ObjectStaticMemberFunction] :
# 1965| r1965_2(D) = Call[ObjectStaticMemberFunction] : func:r1965_1
# 1965| mu1965_3(unknown) = ^CallSideEffect : ~m?
# 1965| r1965_4(glval<D>) = VariableAddress[k] :
# 1965| mu1965_5(D) = Store[k] : &:r1965_4, r1965_2
# 1966| v1966_1(void) = NoOp :
# 1950| v1950_4(void) = ReturnVoid :
# 1950| v1950_5(void) = AliasedUse : ~m?
# 1950| v1950_6(void) = ExitFunction :
# 1968| void test_volatile()
# 1968| Block 0
# 1968| v1968_1(void) = EnterFunction :
# 1968| mu1968_2(unknown) = AliasedDefinition :
# 1968| mu1968_3(unknown) = InitializeNonLocal :
# 1969| r1969_1(glval<int>) = VariableAddress[x] :
# 1969| mu1969_2(int) = Uninitialized[x] : &:r1969_1
# 1970| r1970_1(glval<int>) = VariableAddress[x] :
# 1970| r1970_2(int) = Load[x] : &:r1970_1, ~m?
# 1971| v1971_1(void) = NoOp :
# 1968| v1968_4(void) = ReturnVoid :
# 1968| v1968_5(void) = AliasedUse : ~m?
# 1968| v1968_6(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0