mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 19:49:36 +00:00
a657a32cc8
In r330377 and r338425 we have already identified what constitutes function argument constructors and added stubs in order to prevent confusing them with other temporary object constructors. Now we implement a ConstructionContext sub-class to carry all the necessary information about the construction site, namely call expression and argument index. On the analyzer side, the patch interacts with the recently implemented pre-C++17 copy elision support in an interesting manner. If on the CFG side we didn't find a construction context for the elidable constructor, we build the CFG as if the elidable constructor is not elided, and the non-elided constructor within it is a simple temporary. But the same problem may occur in the analyzer: if the elidable constructor has a construction context but the analyzer doesn't implement such context yet, the analyzer should also try to skip copy elision and still inline the non-elided temporary constructor. This was implemented by adding a "roll back" mechanism: when elision fails, roll back the changes and proceed as if it's a simple temporary. The approach is wonky, but i'm fine with that as long as it's merely a defensive mechanism that should eventually go away once all construction contexts become supported. Differential Revision: https://reviews.llvm.org/D48681. llvm-svn: 338436
67 lines
3.1 KiB
Plaintext
67 lines
3.1 KiB
Plaintext
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w %s > %t 2>&1
|
|
// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,ELIDE,CXX11-ELIDE %s
|
|
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w %s > %t 2>&1
|
|
// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17,ELIDE,CXX17-ELIDE %s
|
|
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w -analyzer-config elide-constructors=false %s > %t 2>&1
|
|
// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,NOELIDE,CXX11-NOELIDE %s
|
|
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w -analyzer-config elide-constructors=false %s > %t 2>&1
|
|
// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17,NOELIDE,CXX17-NOELIDE %s
|
|
|
|
class D {
|
|
public:
|
|
D();
|
|
~D();
|
|
};
|
|
|
|
@interface E {}
|
|
-(void) foo: (D) d;
|
|
-(D) bar;
|
|
@end
|
|
|
|
// CHECK: void passArgumentIntoMessage(E *e)
|
|
// CHECK: 1: e
|
|
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, E *)
|
|
// CXX11-ELIDE-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], class D)
|
|
// CXX11-NOELIDE-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], class D)
|
|
// CXX11-NEXT: 4: [B1.3] (BindTemporary)
|
|
// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class D)
|
|
// CXX11-NEXT: 6: [B1.5]
|
|
// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, class D)
|
|
// CXX11-NEXT: 8: [B1.7] (BindTemporary)
|
|
// Double brackets trigger FileCheck variables, escape.
|
|
// CXX11-NEXT: 9: {{\[}}[B1.2] foo:[B1.8]]
|
|
// CXX11-NEXT: 10: ~D() (Temporary object destructor)
|
|
// CXX11-NEXT: 11: ~D() (Temporary object destructor)
|
|
// CXX17-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.5]+0, class D)
|
|
// CXX17-NEXT: 4: [B1.3] (BindTemporary)
|
|
// Double brackets trigger FileCheck variables, escape.
|
|
// CXX17-NEXT: 5: {{\[}}[B1.2] foo:[B1.4]]
|
|
// CXX17-NEXT: 6: ~D() (Temporary object destructor)
|
|
void passArgumentIntoMessage(E *e) {
|
|
[e foo: D()];
|
|
}
|
|
|
|
// CHECK: void returnObjectFromMessage(E *e)
|
|
// CHECK: [B1]
|
|
// CHECK-NEXT: 1: e
|
|
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, E *)
|
|
// Double brackets trigger FileCheck variables, escape.
|
|
// CXX11-ELIDE-NEXT: 3: {{\[}}[B1.2] bar] (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7])
|
|
// CXX11-NOELIDE-NEXT: 3: {{\[}}[B1.2] bar] (CXXRecordTypedCall, [B1.4], [B1.6])
|
|
// CXX11-NEXT: 4: [B1.3] (BindTemporary)
|
|
// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const class D)
|
|
// CXX11-NEXT: 6: [B1.5]
|
|
// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], class D)
|
|
// CXX11-NEXT: 8: D d = [e bar];
|
|
// CXX11-NEXT: 9: ~D() (Temporary object destructor)
|
|
// CXX11-NEXT: 10: [B1.8].~D() (Implicit destructor)
|
|
// Double brackets trigger FileCheck variables, escape.
|
|
// CXX17-NEXT: 3: {{\[}}[B1.2] bar] (CXXRecordTypedCall, [B1.5], [B1.4])
|
|
// CXX17-NEXT: 4: [B1.3] (BindTemporary)
|
|
// CXX17-NEXT: 5: D d = [e bar];
|
|
// CXX17-NEXT: 6: ~D() (Temporary object destructor)
|
|
// CXX17-NEXT: 7: [B1.5].~D() (Implicit destructor)
|
|
void returnObjectFromMessage(E *e) {
|
|
D d = [e bar];
|
|
}
|