Add tests for member accesses on temporary objects

This commit is contained in:
Dave Bartolomeo
2020-10-20 17:35:12 -04:00
parent 08af0803ff
commit 98e0ae4865
8 changed files with 182 additions and 20 deletions

View File

@@ -6010,10 +6010,13 @@ ir.cpp:
# 715| Type = [TemplateParameter] V
# 715| body: [BlockStmt] { ... }
# 716| 0: [ReturnStmt] return ...
# 716| 0: [Literal] 0
# 716| 0: [TemporaryObjectExpr] temporary object
# 716| Type = [TemplateParameter] T
# 716| Value = [Literal] 0
# 716| ValueCategory = prvalue
# 716| ValueCategory = prvalue(load)
# 716| expr: [Literal] 0
# 716| Type = [TemplateParameter] T
# 716| Value = [Literal] 0
# 716| ValueCategory = prvalue
# 715| [MemberFunction,TemplateFunction] long Outer<long>::Func<U, V>(U, V)
# 715| params:
# 715| 0: [Parameter] x
@@ -10524,6 +10527,14 @@ ir.cpp:
# 1322| Type = [IntPointerType] int *
# 1322| ValueCategory = prvalue(load)
# 1323| 1: [ReturnStmt] return ...
# 1326| [FunctionTemplateInstantiation,TopLevelFunction] Point defaultConstruct<Point>()
# 1326| params:
# 1326| body: [BlockStmt] { ... }
# 1327| 0: [ReturnStmt] return ...
# 1327| 0: [Literal] 0
# 1327| Type = [Struct] Point
# 1327| Value = [Literal] 0
# 1327| ValueCategory = prvalue
# 1326| [FunctionTemplateInstantiation,TopLevelFunction] String defaultConstruct<String>()
# 1326| params:
# 1326| body: [BlockStmt] { ... }
@@ -10535,10 +10546,13 @@ ir.cpp:
# 1326| params:
# 1326| body: [BlockStmt] { ... }
# 1327| 0: [ReturnStmt] return ...
# 1327| 0: [Literal] 0
# 1327| 0: [TemporaryObjectExpr] temporary object
# 1327| Type = [TemplateParameter] T
# 1327| Value = [Literal] 0
# 1327| ValueCategory = prvalue
# 1327| ValueCategory = prvalue(load)
# 1327| expr: [Literal] 0
# 1327| Type = [TemplateParameter] T
# 1327| Value = [Literal] 0
# 1327| ValueCategory = prvalue
# 1326| [FunctionTemplateInstantiation,TopLevelFunction] copy_constructor defaultConstruct<copy_constructor>()
# 1326| params:
# 1326| body: [BlockStmt] { ... }
@@ -10596,6 +10610,10 @@ ir.cpp:
# 1351| params:
# 1353| [MemberFunction] void destructor_only::method()
# 1353| params:
# 1357| [FunctionTemplateInstantiation,TopLevelFunction] void acceptRef<Point>(Point const&)
# 1357| params:
# 1357| 0: [Parameter] v
# 1357| Type = [LValueReferenceType] const Point &
# 1357| [FunctionTemplateInstantiation,TopLevelFunction] void acceptRef<String>(String const&)
# 1357| params:
# 1357| 0: [Parameter] v
@@ -10612,6 +10630,10 @@ ir.cpp:
# 1357| params:
# 1357| 0: [Parameter] v
# 1357| Type = [LValueReferenceType] const destructor_only &
# 1360| [FunctionTemplateInstantiation,TopLevelFunction] void acceptValue<Point>(Point)
# 1360| params:
# 1360| 0: [Parameter] v
# 1360| Type = [Struct] Point
# 1360| [FunctionTemplateInstantiation,TopLevelFunction] void acceptValue<String>(String)
# 1360| params:
# 1360| 0: [Parameter] v
@@ -10628,6 +10650,8 @@ ir.cpp:
# 1360| params:
# 1360| 0: [Parameter] v
# 1360| Type = [Class] destructor_only
# 1363| [FunctionTemplateInstantiation,TopLevelFunction] Point returnValue<Point>()
# 1363| params:
# 1363| [FunctionTemplateInstantiation,TopLevelFunction] String returnValue<String>()
# 1363| params:
# 1363| [TemplateFunction,TopLevelFunction] T returnValue<T>()
@@ -10962,6 +10986,81 @@ ir.cpp:
# 1401| Type = [Class] copy_constructor
# 1401| ValueCategory = prvalue
# 1402| 9: [ReturnStmt] return ...
# 1404| [TopLevelFunction] void temporary_point()
# 1404| params:
# 1404| body: [BlockStmt] { ... }
# 1405| 0: [DeclStmt] declaration
# 1405| 0: [VariableDeclarationEntry] definition of p
# 1405| Type = [Struct] Point
# 1405| init: [Initializer] initializer for p
# 1405| expr: [FunctionCall] call to returnValue
# 1405| Type = [Struct] Point
# 1405| ValueCategory = prvalue
# 1406| 1: [DeclStmt] declaration
# 1406| 0: [VariableDeclarationEntry] definition of rp
# 1406| Type = [LValueReferenceType] const Point &
# 1406| init: [Initializer] initializer for rp
# 1406| expr: [ReferenceToExpr] (reference to)
# 1406| Type = [LValueReferenceType] const Point &
# 1406| ValueCategory = prvalue
# 1406| expr: [CStyleCast] (const Point)...
# 1406| Conversion = [GlvalueConversion] glvalue conversion
# 1406| Type = [SpecifiedType] const Point
# 1406| ValueCategory = lvalue
# 1406| expr: [TemporaryObjectExpr] temporary object
# 1406| Type = [Struct] Point
# 1406| ValueCategory = lvalue
# 1406| expr: [FunctionCall] call to returnValue
# 1406| Type = [Struct] Point
# 1406| ValueCategory = prvalue
# 1408| 2: [ExprStmt] ExprStmt
# 1408| 0: [FunctionCall] call to acceptRef
# 1408| Type = [VoidType] void
# 1408| ValueCategory = prvalue
# 1408| 0: [ReferenceToExpr] (reference to)
# 1408| Type = [LValueReferenceType] const Point &
# 1408| ValueCategory = prvalue
# 1408| expr: [CStyleCast] (const Point)...
# 1408| Conversion = [GlvalueConversion] glvalue conversion
# 1408| Type = [SpecifiedType] const Point
# 1408| ValueCategory = lvalue
# 1408| expr: [VariableAccess] p
# 1408| Type = [Struct] Point
# 1408| ValueCategory = lvalue
# 1409| 3: [ExprStmt] ExprStmt
# 1409| 0: [FunctionCall] call to acceptValue
# 1409| Type = [VoidType] void
# 1409| ValueCategory = prvalue
# 1409| 0: [VariableAccess] p
# 1409| Type = [Struct] Point
# 1409| ValueCategory = prvalue(load)
# 1410| 4: [ExprStmt] ExprStmt
# 1410| 0: [ValueFieldAccess] x
# 1410| Type = [IntType] int
# 1410| Value = [ValueFieldAccess] 0
# 1410| ValueCategory = prvalue
# 1410| -1: [TemporaryObjectExpr] temporary object
# 1410| Type = [Struct] Point
# 1410| ValueCategory = prvalue(load)
# 1410| expr: [Literal] 0
# 1410| Type = [Struct] Point
# 1410| Value = [Literal] 0
# 1410| ValueCategory = prvalue
# 1411| 5: [DeclStmt] declaration
# 1411| 0: [VariableDeclarationEntry] definition of y
# 1411| Type = [IntType] int
# 1411| init: [Initializer] initializer for y
# 1411| expr: [ValueFieldAccess] y
# 1411| Type = [IntType] int
# 1411| ValueCategory = prvalue
# 1411| -1: [FunctionCall] call to returnValue
# 1411| Type = [Struct] Point
# 1411| ValueCategory = prvalue
# 1413| 6: [ExprStmt] ExprStmt
# 1413| 0: [FunctionCall] call to defaultConstruct
# 1413| Type = [Struct] Point
# 1413| ValueCategory = prvalue
# 1414| 7: [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| params:

View File

@@ -22,14 +22,8 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1401:45:1401:45 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1391:6:1391:31 | void temporary_copy_constructor() | void temporary_copy_constructor() |
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
| ir.cpp:1373:14:1373:18 | Call: call to c_str | Call instruction 'Call: call to c_str' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1365:6:1365:21 | void temporary_string() | void temporary_string() |
| ir.cpp:1374:27:1374:31 | Call: call to c_str | Call instruction 'Call: call to c_str' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1365:6:1365:21 | void temporary_string() | void temporary_string() |
| ir.cpp:1385:23:1385:28 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1379:6:1379:30 | void temporary_destructor_only() | void temporary_destructor_only() |
| ir.cpp:1386:36:1386:41 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1379:6:1379:30 | void temporary_destructor_only() | void temporary_destructor_only() |
| ir.cpp:1397:24:1397:29 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1391:6:1391:31 | void temporary_copy_constructor() | void temporary_copy_constructor() |
| ir.cpp:1398:37:1398:42 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1391:6:1391:31 | void temporary_copy_constructor() | void temporary_copy_constructor() |
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType

View File

@@ -22,14 +22,8 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1401:45:1401:45 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1391:6:1391:31 | void temporary_copy_constructor() | void temporary_copy_constructor() |
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
| ir.cpp:1373:14:1373:18 | Call: call to c_str | Call instruction 'Call: call to c_str' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1365:6:1365:21 | void temporary_string() | void temporary_string() |
| ir.cpp:1374:27:1374:31 | Call: call to c_str | Call instruction 'Call: call to c_str' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1365:6:1365:21 | void temporary_string() | void temporary_string() |
| ir.cpp:1385:23:1385:28 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1379:6:1379:30 | void temporary_destructor_only() | void temporary_destructor_only() |
| ir.cpp:1386:36:1386:41 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1379:6:1379:30 | void temporary_destructor_only() | void temporary_destructor_only() |
| ir.cpp:1397:24:1397:29 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1391:6:1391:31 | void temporary_copy_constructor() | void temporary_copy_constructor() |
| ir.cpp:1398:37:1398:42 | Call: call to method | Call instruction 'Call: call to method' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:1391:6:1391:31 | void temporary_copy_constructor() | void temporary_copy_constructor() |
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType

View File

@@ -1401,4 +1401,16 @@ void temporary_copy_constructor() {
int y = returnValue<copy_constructor>().y;
}
void temporary_point() {
Point p = returnValue<Point>(); // No temporary
const Point& rp = returnValue<Point>(); // Binding a reference variable to a temporary
acceptRef(p); // No temporary
acceptValue(p);
Point().x;
int y = returnValue<Point>().y;
defaultConstruct<Point>();
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -22,6 +22,7 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -7441,6 +7441,19 @@ ir.cpp:
# 1320| v1320_10(void) = AliasedUse : ~m?
# 1320| v1320_11(void) = ExitFunction :
# 1326| Point defaultConstruct<Point>()
# 1326| Block 0
# 1326| v1326_1(void) = EnterFunction :
# 1326| mu1326_2(unknown) = AliasedDefinition :
# 1326| mu1326_3(unknown) = InitializeNonLocal :
# 1327| r1327_1(glval<Point>) = VariableAddress[#return] :
# 1327| r1327_2(Point) = Constant[0] :
# 1327| mu1327_3(Point) = Store[#return] : &:r1327_1, r1327_2
# 1326| r1326_4(glval<Point>) = VariableAddress[#return] :
# 1326| v1326_5(void) = ReturnValue : &:r1326_4, ~m?
# 1326| v1326_6(void) = AliasedUse : ~m?
# 1326| v1326_7(void) = ExitFunction :
# 1326| String defaultConstruct<String>()
# 1326| Block 0
# 1326| v1326_1(void) = EnterFunction :
@@ -7746,6 +7759,53 @@ ir.cpp:
# 1391| v1391_5(void) = AliasedUse : ~m?
# 1391| v1391_6(void) = ExitFunction :
# 1404| void temporary_point()
# 1404| Block 0
# 1404| v1404_1(void) = EnterFunction :
# 1404| mu1404_2(unknown) = AliasedDefinition :
# 1404| mu1404_3(unknown) = InitializeNonLocal :
# 1405| r1405_1(glval<Point>) = VariableAddress[p] :
# 1405| r1405_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1405| r1405_3(Point) = Call[returnValue] : func:r1405_2
# 1405| mu1405_4(unknown) = ^CallSideEffect : ~m?
# 1405| mu1405_5(Point) = Store[p] : &:r1405_1, r1405_3
# 1406| r1406_1(glval<Point &>) = VariableAddress[rp] :
# 1406| r1406_2(glval<Point>) = VariableAddress[#temp1406:23] :
# 1406| r1406_3(glval<unknown>) = FunctionAddress[returnValue] :
# 1406| r1406_4(Point) = Call[returnValue] : func:r1406_3
# 1406| mu1406_5(unknown) = ^CallSideEffect : ~m?
# 1406| mu1406_6(Point) = Store[#temp1406:23] : &:r1406_2, r1406_4
# 1406| r1406_7(glval<Point>) = Convert : r1406_2
# 1406| r1406_8(Point &) = CopyValue : r1406_7
# 1406| mu1406_9(Point &) = Store[rp] : &:r1406_1, r1406_8
# 1408| r1408_1(glval<unknown>) = FunctionAddress[acceptRef] :
# 1408| r1408_2(glval<Point>) = VariableAddress[p] :
# 1408| r1408_3(glval<Point>) = Convert : r1408_2
# 1408| r1408_4(Point &) = CopyValue : r1408_3
# 1408| v1408_5(void) = Call[acceptRef] : func:r1408_1, 0:r1408_4
# 1408| mu1408_6(unknown) = ^CallSideEffect : ~m?
# 1408| v1408_7(void) = ^BufferReadSideEffect[0] : &:r1408_4, ~m?
# 1408| mu1408_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r1408_4
# 1409| r1409_1(glval<unknown>) = FunctionAddress[acceptValue] :
# 1409| r1409_2(glval<Point>) = VariableAddress[p] :
# 1409| r1409_3(Point) = Load[p] : &:r1409_2, ~m?
# 1409| v1409_4(void) = Call[acceptValue] : func:r1409_1, 0:r1409_3
# 1409| mu1409_5(unknown) = ^CallSideEffect : ~m?
# 1410| r1410_1(int) = Constant[0] :
# 1411| r1411_1(glval<int>) = VariableAddress[y] :
# 1411| r1411_2(glval<unknown>) = FunctionAddress[returnValue] :
# 1411| r1411_3(Point) = Call[returnValue] : func:r1411_2
# 1411| mu1411_4(unknown) = ^CallSideEffect : ~m?
# 1411| r1411_5(glval<int>) = FieldAddress[y] : r1411_3
# 1411| mu1411_6(int) = Store[y] : &:r1411_1, r1411_5
# 1413| r1413_1(glval<unknown>) = FunctionAddress[defaultConstruct] :
# 1413| r1413_2(Point) = Call[defaultConstruct] : func:r1413_1
# 1413| mu1413_3(unknown) = ^CallSideEffect : ~m?
# 1414| v1414_1(void) = NoOp :
# 1404| v1404_4(void) = ReturnVoid :
# 1404| v1404_5(void) = AliasedUse : ~m?
# 1404| v1404_6(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -22,6 +22,7 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes

View File

@@ -22,6 +22,7 @@ wronglyMarkedAsConflated
invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
| ir.cpp:1411:34:1411:34 | FieldAddress: y | FieldAddress instruction 'FieldAddress: y' has an object address operand that is not an address, in function '$@'. | ir.cpp:1404:6:1404:20 | void temporary_point() | void temporary_point() |
thisArgumentIsNonPointer
missingCanonicalLanguageType
multipleCanonicalLanguageTypes