r338135 - Add missing temporary materialization conversion on left-hand side of .
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 27 10:13:19 PDT 2018
Author: rsmith
Date: Fri Jul 27 10:13:18 2018
New Revision: 338135
URL: http://llvm.org/viewvc/llvm-project?rev=338135&view=rev
Log:
Add missing temporary materialization conversion on left-hand side of .
in some member function calls.
Specifically, when calling a conversion function, we would fail to
create the AST node representing materialization of the class object.
Modified:
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
cfe/trunk/test/Analysis/lambda-notes.cpp
cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
cfe/trunk/test/CodeGenCXX/stack-reuse-miscompile.cpp
cfe/trunk/test/CodeGenObjCXX/literals.mm
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri Jul 27 10:13:18 2018
@@ -4408,9 +4408,11 @@ tryAgain:
auto *LE = cast<LambdaExpr>(E);
CFGBlock *B = Block;
for (Expr *Init : LE->capture_inits()) {
- if (CFGBlock *R = VisitForTemporaryDtors(
- Init, /*BindToTemporary=*/false, Context))
- B = R;
+ if (Init) {
+ if (CFGBlock *R = VisitForTemporaryDtors(
+ Init, /*BindToTemporary=*/false, Context))
+ B = R;
+ }
}
return B;
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 27 10:13:18 2018
@@ -7138,6 +7138,10 @@ static bool IsArithmeticBinaryExpr(Expr
E = E->IgnoreImpCasts();
E = E->IgnoreConversionOperator();
E = E->IgnoreImpCasts();
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ E = MTE->GetTemporaryExpr();
+ E = E->IgnoreImpCasts();
+ }
// Built-in binary operator.
if (BinaryOperator *OP = dyn_cast<BinaryOperator>(E)) {
@@ -7185,6 +7189,8 @@ static bool ExprLooksBoolean(Expr *E) {
return OP->getOpcode() == UO_LNot;
if (E->getType()->isPointerType())
return true;
+ // FIXME: What about overloaded operator calls returning "unspecified boolean
+ // type"s (commonly pointer-to-members)?
return false;
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Jul 27 10:13:18 2018
@@ -7114,10 +7114,17 @@ ExprResult Sema::ActOnPseudoDestructorEx
ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
CXXConversionDecl *Method,
bool HadMultipleCandidates) {
+ // Convert the expression to match the conversion function's implicit object
+ // parameter.
+ ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr,
+ FoundDecl, Method);
+ if (Exp.isInvalid())
+ return true;
+
if (Method->getParent()->isLambda() &&
Method->getConversionType()->isBlockPointerType()) {
// This is a lambda coversion to block pointer; check if the argument
- // is a LambdaExpr.
+ // was a LambdaExpr.
Expr *SubE = E;
CastExpr *CE = dyn_cast<CastExpr>(SubE);
if (CE && CE->getCastKind() == CK_NoOp)
@@ -7134,22 +7141,16 @@ ExprResult Sema::BuildCXXMemberCallExpr(
DiagnosticErrorTrap Trap(Diags);
PushExpressionEvaluationContext(
ExpressionEvaluationContext::PotentiallyEvaluated);
- ExprResult Exp = BuildBlockForLambdaConversion(E->getExprLoc(),
- E->getExprLoc(),
- Method, E);
+ ExprResult BlockExp = BuildBlockForLambdaConversion(
+ Exp.get()->getExprLoc(), Exp.get()->getExprLoc(), Method, Exp.get());
PopExpressionEvaluationContext();
- if (Exp.isInvalid())
- Diag(E->getExprLoc(), diag::note_lambda_to_block_conv);
- return Exp;
+ if (BlockExp.isInvalid())
+ Diag(Exp.get()->getExprLoc(), diag::note_lambda_to_block_conv);
+ return BlockExp;
}
}
- ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr,
- FoundDecl, Method);
- if (Exp.isInvalid())
- return true;
-
MemberExpr *ME = new (Context) MemberExpr(
Exp.get(), /*IsArrow=*/false, SourceLocation(), Method, SourceLocation(),
Context.BoundMemberTy, VK_RValue, OK_Ordinary);
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Jul 27 10:13:18 2018
@@ -7406,16 +7406,6 @@ InitializationSequence::Perform(Sema &S,
if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
return ExprError();
- // FIXME: Should we move this initialization into a separate
- // derived-to-base conversion? I believe the answer is "no", because
- // we don't want to turn off access control here for c-style casts.
- CurInit = S.PerformObjectArgumentInitialization(CurInit.get(),
- /*Qualifier=*/nullptr,
- FoundFn, Conversion);
- if (CurInit.isInvalid())
- return ExprError();
-
- // Build the actual call to the conversion function.
CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion,
HadMultipleCandidates);
if (CurInit.isInvalid())
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jul 27 10:13:18 2018
@@ -5165,6 +5165,13 @@ Sema::PerformObjectArgumentInitializatio
FromRecordType = From->getType();
DestType = ImplicitParamRecordType;
FromClassification = From->Classify(Context);
+
+ // When performing member access on an rvalue, materialize a temporary.
+ if (From->isRValue()) {
+ From = CreateMaterializeTemporaryExpr(FromRecordType, From,
+ Method->getRefQualifier() !=
+ RefQualifierKind::RQ_RValue);
+ }
}
// Note that we always use the true parent context when performing
Modified: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cfg-rich-constructors.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp (original)
+++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Fri Jul 27 10:13:18 2018
@@ -464,14 +464,14 @@ void simpleTemporary() {
C();
}
-// TODO: Should provide construction context for the constructor,
// CHECK: void temporaryInCondition()
-// CHECK: 1: C() (CXXConstructExpr, class C)
-// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, NoOp, const class C)
-// CHECK-NEXT: 3: [B2.2].operator bool
-// CHECK-NEXT: 4: [B2.2]
-// CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK-NEXT: T: if [B2.5]
+// CHECK: 1: C() (CXXConstructExpr, [B2.2], class C)
+// CHECK-NEXT: 2: [B2.1]
+// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class C)
+// CHECK-NEXT: 4: [B2.3].operator bool
+// CHECK-NEXT: 5: [B2.3]
+// CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK-NEXT: T: if [B2.6]
void temporaryInCondition() {
if (C());
}
@@ -583,14 +583,15 @@ void simpleTemporary() {
}
// CHECK: void temporaryInCondition()
-// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], class temporary_object_expr_with_dtors::D)
+// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B2.2], [B2.3], class temporary_object_expr_with_dtors::D)
// CHECK-NEXT: 2: [B2.1] (BindTemporary)
-// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
-// CHECK-NEXT: 4: [B2.3].operator bool
-// CHECK-NEXT: 5: [B2.3]
-// CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK-NEXT: 7: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
-// CHECK-NEXT: T: if [B2.6]
+// CHECK-NEXT: 3: [B2.2]
+// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
+// CHECK-NEXT: 5: [B2.4].operator bool
+// CHECK-NEXT: 6: [B2.4]
+// CHECK-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK-NEXT: 8: ~temporary_object_expr_with_dtors::D() (Temporary object destructor)
+// CHECK-NEXT: T: if [B2.7]
void temporaryInCondition() {
if (D());
}
@@ -693,23 +694,25 @@ void referenceWithFunctionalCast() {
// Test the condition constructor, we don't care about branch constructors here.
// CHECK: void constructorInTernaryCondition()
// CXX11: 1: 1
-// CXX11-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], class temporary_object_expr_with_dtors::D)
+// CXX11-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], [B7.5], class temporary_object_expr_with_dtors::D)
// CXX11-NEXT: 3: [B7.2] (BindTemporary)
// CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B7.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
-// CXX11-NEXT: 5: [B7.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
-// CXX11-NEXT: 6: [B7.5].operator bool
-// CXX11-NEXT: 7: [B7.5]
-// CXX11-NEXT: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX11-NEXT: T: [B7.8] ? ... : ...
+// CXX11-NEXT: 5: [B7.4]
+// CXX11-NEXT: 6: [B7.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
+// CXX11-NEXT: 7: [B7.6].operator bool
+// CXX11-NEXT: 8: [B7.6]
+// CXX11-NEXT: 9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX11-NEXT: T: [B7.9] ? ... : ...
// CXX17: 1: 1
-// CXX17-NEXT: 2: [B4.1] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D)
+// CXX17-NEXT: 2: [B4.1] (CXXConstructExpr, [B4.3], [B4.5], class temporary_object_expr_with_dtors::D)
// CXX17-NEXT: 3: [B4.2] (BindTemporary)
// CXX17-NEXT: 4: temporary_object_expr_with_dtors::D([B4.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D)
-// CXX17-NEXT: 5: [B4.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
-// CXX17-NEXT: 6: [B4.5].operator bool
-// CXX17-NEXT: 7: [B4.5]
-// CXX17-NEXT: 8: [B4.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX17-NEXT: T: [B4.8] ? ... : ...
+// CXX17-NEXT: 5: [B4.4]
+// CXX17-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)
+// CXX17-NEXT: 7: [B4.6].operator bool
+// CXX17-NEXT: 8: [B4.6]
+// CXX17-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CXX17-NEXT: T: [B4.9] ? ... : ...
void constructorInTernaryCondition() {
const D &d = D(1) ? D(2) : D(3);
}
Modified: cfe/trunk/test/Analysis/lambda-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/lambda-notes.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/lambda-notes.cpp (original)
+++ cfe/trunk/test/Analysis/lambda-notes.cpp Fri Jul 27 10:13:18 2018
@@ -69,7 +69,7 @@ void diagnosticFromLambda() {
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>12</integer>
-// CHECK-NEXT: <key>col</key><integer>5</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Fri Jul 27 10:13:18 2018
@@ -311,44 +311,48 @@ const C &bar3(bool coin) {
// CHECK: Succs (1): B1
// CHECK: [B1]
// WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.3], class A)
// CHECK: 2: [B1.1] (BindTemporary)
-// CHECK: 3: [B1.2].operator int
-// CHECK: 4: [B1.2]
-// CHECK: 5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int)
-// WARNINGS: 7: B() (CXXConstructExpr, class B)
-// ANALYZER: 7: B() (CXXConstructExpr, [B1.8], class B)
-// CHECK: 8: [B1.7] (BindTemporary)
-// CHECK: 9: [B1.8].operator int
-// CHECK: 10: [B1.8]
-// CHECK: 11: [B1.10] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 12: int([B1.11]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK: 13: [B1.6] + [B1.12]
-// CHECK: 14: int a = int(A()) + int(B());
-// CHECK: 15: ~B() (Temporary object destructor)
-// CHECK: 16: ~A() (Temporary object destructor)
-// CHECK: 17: foo
-// CHECK: 18: [B1.17] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
-// WARNINGS: 19: A() (CXXConstructExpr, class A)
-// ANALYZER: 19: A() (CXXConstructExpr, [B1.20], class A)
-// CHECK: 20: [B1.19] (BindTemporary)
-// CHECK: 21: [B1.20].operator int
-// CHECK: 22: [B1.20]
-// CHECK: 23: [B1.22] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 24: int([B1.23]) (CXXFunctionalCastExpr, NoOp, int)
-// WARNINGS: 25: B() (CXXConstructExpr, class B)
-// ANALYZER: 25: B() (CXXConstructExpr, [B1.26], class B)
-// CHECK: 26: [B1.25] (BindTemporary)
-// CHECK: 27: [B1.26].operator int
-// CHECK: 28: [B1.26]
-// CHECK: 29: [B1.28] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 30: int([B1.29]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK: 31: [B1.24] + [B1.30]
-// CHECK: 32: [B1.18]([B1.31])
-// CHECK: 33: ~B() (Temporary object destructor)
-// CHECK: 34: ~A() (Temporary object destructor)
-// CHECK: 35: int b;
+// CHECK: 3: [B1.2]
+// CHECK: 4: [B1.3].operator int
+// CHECK: 5: [B1.3]
+// CHECK: 6: [B1.5] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 7: int([B1.6]) (CXXFunctionalCastExpr, NoOp, int)
+// WARNINGS: 8: B() (CXXConstructExpr, class B)
+// ANALYZER: 8: B() (CXXConstructExpr, [B1.9], [B1.10], class B)
+// CHECK: 9: [B1.8] (BindTemporary)
+// CHECK: 10: [B1.9]
+// CHECK: 11: [B1.10].operator int
+// CHECK: 12: [B1.10]
+// CHECK: 13: [B1.12] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 14: int([B1.13]) (CXXFunctionalCastExpr, NoOp, int)
+// CHECK: 15: [B1.7] + [B1.14]
+// CHECK: 16: int a = int(A()) + int(B());
+// CHECK: 17: ~B() (Temporary object destructor)
+// CHECK: 18: ~A() (Temporary object destructor)
+// CHECK: 19: foo
+// CHECK: 20: [B1.19] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
+// WARNINGS: 21: A() (CXXConstructExpr, class A)
+// ANALYZER: 21: A() (CXXConstructExpr, [B1.22], [B1.23], class A)
+// CHECK: 22: [B1.21] (BindTemporary)
+// CHECK: 23: [B1.22]
+// CHECK: 24: [B1.23].operator int
+// CHECK: 25: [B1.23]
+// CHECK: 26: [B1.25] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 27: int([B1.26]) (CXXFunctionalCastExpr, NoOp, int)
+// WARNINGS: 28: B() (CXXConstructExpr, class B)
+// ANALYZER: 28: B() (CXXConstructExpr, [B1.29], [B1.30], class B)
+// CHECK: 29: [B1.28] (BindTemporary)
+// CHECK: 30: [B1.29]
+// CHECK: 31: [B1.30].operator int
+// CHECK: 32: [B1.30]
+// CHECK: 33: [B1.32] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 34: int([B1.33]) (CXXFunctionalCastExpr, NoOp, int)
+// CHECK: 35: [B1.27] + [B1.34]
+// CHECK: 36: [B1.20]([B1.35])
+// CHECK: 37: ~B() (Temporary object destructor)
+// CHECK: 38: ~A() (Temporary object destructor)
+// CHECK: 39: int b;
// CHECK: Preds (1): B2
// CHECK: Succs (1): B0
// CHECK: [B0 (EXIT)]
@@ -365,18 +369,19 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B3
// CHECK: Succs (1): B1
// CHECK: [B3]
-// CHECK: 1: [B5.8] && [B4.5]
+// CHECK: 1: [B5.9] && [B4.6]
// CHECK: 2: [B5.3]([B3.1])
// CHECK: T: (Temp Dtor) [B4.2]
// CHECK: Preds (2): B4 B5
// CHECK: Succs (2): B2 B1
// CHECK: [B4]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B4.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B4.2], [B4.3], class B)
// CHECK: 2: [B4.1] (BindTemporary)
-// CHECK: 3: [B4.2].operator bool
-// CHECK: 4: [B4.2]
-// CHECK: 5: [B4.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: 3: [B4.2]
+// CHECK: 4: [B4.3].operator bool
+// CHECK: 5: [B4.3]
+// CHECK: 6: [B4.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
// CHECK: Preds (1): B5
// CHECK: Succs (1): B3
// CHECK: [B5]
@@ -384,12 +389,13 @@ const C &bar3(bool coin) {
// CHECK: 2: foo
// CHECK: 3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
// WARNINGS: 4: A() (CXXConstructExpr, class A)
-// ANALYZER: 4: A() (CXXConstructExpr, [B5.5], class A)
+// ANALYZER: 4: A() (CXXConstructExpr, [B5.5], [B5.6], class A)
// CHECK: 5: [B5.4] (BindTemporary)
-// CHECK: 6: [B5.5].operator bool
-// CHECK: 7: [B5.5]
-// CHECK: 8: [B5.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B5.8] && ...
+// CHECK: 6: [B5.5]
+// CHECK: 7: [B5.6].operator bool
+// CHECK: 8: [B5.6]
+// CHECK: 9: [B5.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B5.9] && ...
// CHECK: Preds (2): B6 B7
// CHECK: Succs (2): B4 B3
// CHECK: [B6]
@@ -397,28 +403,30 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B7
// CHECK: Succs (1): B5
// CHECK: [B7]
-// CHECK: 1: [B9.5] && [B8.5]
+// CHECK: 1: [B9.6] && [B8.6]
// CHECK: 2: bool a = A() && B();
// CHECK: T: (Temp Dtor) [B8.2]
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B6 B5
// CHECK: [B8]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B8.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B8.2], [B8.3], class B)
// CHECK: 2: [B8.1] (BindTemporary)
-// CHECK: 3: [B8.2].operator bool
-// CHECK: 4: [B8.2]
-// CHECK: 5: [B8.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: 3: [B8.2]
+// CHECK: 4: [B8.3].operator bool
+// CHECK: 5: [B8.3]
+// CHECK: 6: [B8.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
// CHECK: Preds (1): B9
// CHECK: Succs (1): B7
// CHECK: [B9]
// WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B9.2], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B9.2], [B9.3], class A)
// CHECK: 2: [B9.1] (BindTemporary)
-// CHECK: 3: [B9.2].operator bool
-// CHECK: 4: [B9.2]
-// CHECK: 5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B9.5] && ...
+// CHECK: 3: [B9.2]
+// CHECK: 4: [B9.3].operator bool
+// CHECK: 5: [B9.3]
+// CHECK: 6: [B9.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B9.6] && ...
// CHECK: Preds (1): B10
// CHECK: Succs (2): B8 B7
// CHECK: [B0 (EXIT)]
@@ -435,18 +443,19 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B3
// CHECK: Succs (1): B1
// CHECK: [B3]
-// CHECK: 1: [B5.8] || [B4.5]
+// CHECK: 1: [B5.9] || [B4.6]
// CHECK: 2: [B5.3]([B3.1])
// CHECK: T: (Temp Dtor) [B4.2]
// CHECK: Preds (2): B4 B5
// CHECK: Succs (2): B2 B1
// CHECK: [B4]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B4.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B4.2], [B4.3], class B)
// CHECK: 2: [B4.1] (BindTemporary)
-// CHECK: 3: [B4.2].operator bool
-// CHECK: 4: [B4.2]
-// CHECK: 5: [B4.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: 3: [B4.2]
+// CHECK: 4: [B4.3].operator bool
+// CHECK: 5: [B4.3]
+// CHECK: 6: [B4.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
// CHECK: Preds (1): B5
// CHECK: Succs (1): B3
// CHECK: [B5]
@@ -454,12 +463,13 @@ const C &bar3(bool coin) {
// CHECK: 2: foo
// CHECK: 3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
// WARNINGS: 4: A() (CXXConstructExpr, class A)
-// ANALYZER: 4: A() (CXXConstructExpr, [B5.5], class A)
+// ANALYZER: 4: A() (CXXConstructExpr, [B5.5], [B5.6], class A)
// CHECK: 5: [B5.4] (BindTemporary)
-// CHECK: 6: [B5.5].operator bool
-// CHECK: 7: [B5.5]
-// CHECK: 8: [B5.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B5.8] || ...
+// CHECK: 6: [B5.5]
+// CHECK: 7: [B5.6].operator bool
+// CHECK: 8: [B5.6]
+// CHECK: 9: [B5.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B5.9] || ...
// CHECK: Preds (2): B6 B7
// CHECK: Succs (2): B3 B4
// CHECK: [B6]
@@ -467,28 +477,30 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B7
// CHECK: Succs (1): B5
// CHECK: [B7]
-// CHECK: 1: [B9.5] || [B8.5]
+// CHECK: 1: [B9.6] || [B8.6]
// CHECK: 2: bool a = A() || B();
// CHECK: T: (Temp Dtor) [B8.2]
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B6 B5
// CHECK: [B8]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B8.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B8.2], [B8.3], class B)
// CHECK: 2: [B8.1] (BindTemporary)
-// CHECK: 3: [B8.2].operator bool
-// CHECK: 4: [B8.2]
-// CHECK: 5: [B8.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: 3: [B8.2]
+// CHECK: 4: [B8.3].operator bool
+// CHECK: 5: [B8.3]
+// CHECK: 6: [B8.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
// CHECK: Preds (1): B9
// CHECK: Succs (1): B7
// CHECK: [B9]
// WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B9.2], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B9.2], [B9.3], class A)
// CHECK: 2: [B9.1] (BindTemporary)
-// CHECK: 3: [B9.2].operator bool
-// CHECK: 4: [B9.2]
-// CHECK: 5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B9.5] || ...
+// CHECK: 3: [B9.2]
+// CHECK: 4: [B9.3].operator bool
+// CHECK: 5: [B9.3]
+// CHECK: 6: [B9.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B9.6] || ...
// CHECK: Preds (1): B10
// CHECK: Succs (2): B7 B8
// CHECK: [B0 (EXIT)]
@@ -517,13 +529,14 @@ const C &bar3(bool coin) {
// CHECK: [B4]
// CHECK: 1: ~B() (Temporary object destructor)
// WARNINGS: 2: B() (CXXConstructExpr, class B)
-// ANALYZER: 2: B() (CXXConstructExpr, [B4.3], class B)
+// ANALYZER: 2: B() (CXXConstructExpr, [B4.3], [B4.4], class B)
// CHECK: 3: [B4.2] (BindTemporary)
-// CHECK: 4: [B4.3].operator bool
-// CHECK: 5: [B4.3]
-// CHECK: 6: [B4.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: 7: ~B() (Temporary object destructor)
-// CHECK: T: if [B4.6]
+// CHECK: 4: [B4.3]
+// CHECK: 5: [B4.4].operator bool
+// CHECK: 6: [B4.4]
+// CHECK: 7: [B4.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: 8: ~B() (Temporary object destructor)
+// CHECK: T: if [B4.7]
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B3 B2
// CHECK: [B5]
@@ -539,7 +552,7 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B7
// CHECK: Succs (1): B4
// CHECK: [B7]
-// CHECK: 1: [B10.5] ? [B8.6] : [B9.15]
+// CHECK: 1: [B10.6] ? [B8.6] : [B9.16]
// CHECK: 2: [B7.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B7.2]
// WARNINGS: 4: [B7.3] (CXXConstructExpr, class A)
@@ -561,33 +574,35 @@ const C &bar3(bool coin) {
// CHECK: Succs (1): B7
// CHECK: [B9]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B9.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B9.2], [B9.3], class B)
// CHECK: 2: [B9.1] (BindTemporary)
-// CHECK: 3: [B9.2].operator A
-// CHECK: 4: [B9.2]
-// CHECK: 5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, class A)
-// CHECK: 6: [B9.5] (BindTemporary)
-// CHECK: 7: [B9.6] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 8: [B9.7]
-// WARNINGS: 9: [B9.8] (CXXConstructExpr, class A)
-// ANALYZER: 9: [B9.8] (CXXConstructExpr, [B9.10], [B9.13], [B9.14], class A)
-// CHECK: 10: [B9.9] (BindTemporary)
-// CHECK: 11: A([B9.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
-// CHECK: 12: [B9.11] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 13: [B9.12]
-// WARNINGS: 14: [B9.13] (CXXConstructExpr, class A)
-// ANALYZER: 14: [B9.13] (CXXConstructExpr, [B9.15], [B7.3], [B7.4], class A)
-// CHECK: 15: [B9.14] (BindTemporary)
+// CHECK: 3: [B9.2]
+// CHECK: 4: [B9.3].operator A
+// CHECK: 5: [B9.3]
+// CHECK: 6: [B9.5] (ImplicitCastExpr, UserDefinedConversion, class A)
+// CHECK: 7: [B9.6] (BindTemporary)
+// CHECK: 8: [B9.7] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 9: [B9.8]
+// WARNINGS: 10: [B9.9] (CXXConstructExpr, class A)
+// ANALYZER: 10: [B9.9] (CXXConstructExpr, [B9.11], [B9.14], [B9.15], class A)
+// CHECK: 11: [B9.10] (BindTemporary)
+// CHECK: 12: A([B9.11]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
+// CHECK: 13: [B9.12] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 14: [B9.13]
+// WARNINGS: 15: [B9.14] (CXXConstructExpr, class A)
+// ANALYZER: 15: [B9.14] (CXXConstructExpr, [B9.16], [B7.3], [B7.4], class A)
+// CHECK: 16: [B9.15] (BindTemporary)
// CHECK: Preds (1): B10
// CHECK: Succs (1): B7
// CHECK: [B10]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B10.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B10.2], [B10.3], class B)
// CHECK: 2: [B10.1] (BindTemporary)
-// CHECK: 3: [B10.2].operator bool
-// CHECK: 4: [B10.2]
-// CHECK: 5: [B10.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B10.5] ? ... : ...
+// CHECK: 3: [B10.2]
+// CHECK: 4: [B10.3].operator bool
+// CHECK: 5: [B10.3]
+// CHECK: 6: [B10.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B10.6] ? ... : ...
// CHECK: Preds (1): B11
// CHECK: Succs (2): B8 B9
// CHECK: [B0 (EXIT)]
@@ -650,13 +665,14 @@ const C &bar3(bool coin) {
// CHECK: Succs (1): B0
// CHECK: [B3]
// WARNINGS: 1: C() (CXXConstructExpr, struct C)
-// ANALYZER: 1: C() (CXXConstructExpr, [B3.2], struct C)
+// ANALYZER: 1: C() (CXXConstructExpr, [B3.2], [B3.3], struct C)
// CHECK: 2: [B3.1] (BindTemporary)
-// CHECK: 3: [B3.2].operator bool
-// CHECK: 4: [B3.2]
-// CHECK: 5: [B3.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: 6: ~C() (Temporary object destructor)
-// CHECK: T: if [B3.5]
+// CHECK: 3: [B3.2]
+// CHECK: 4: [B3.3].operator bool
+// CHECK: 5: [B3.3]
+// CHECK: 6: [B3.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: 7: ~C() (Temporary object destructor)
+// CHECK: T: if [B3.6]
// CHECK: Preds (1): B4
// CHECK: Succs (2): B2 B1
// CHECK: [B0 (EXIT)]
@@ -710,11 +726,13 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B3
// CHECK: Succs (1): B0
// CHECK: [B3]
-// CHECK: 1: D() (CXXConstructExpr, struct D)
-// CHECK: 2: [B3.1].operator bool
-// CHECK: 3: [B3.1]
-// CHECK: 4: [B3.3] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: if [B3.4]
+// WARNINGS: 1: D() (CXXConstructExpr, struct D)
+// ANALYZER: 1: D() (CXXConstructExpr, [B3.2], struct D)
+// CHECK: 2: [B3.1]
+// CHECK: 3: [B3.2].operator bool
+// CHECK: 4: [B3.2]
+// CHECK: 5: [B3.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: if [B3.5]
// CHECK: Preds (1): B4
// CHECK: Succs (2): B2 B1
// CHECK: [B0 (EXIT)]
@@ -780,7 +798,7 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.8] ? [B5.6] : [B6.15]
+// CHECK: 1: [B7.9] ? [B5.6] : [B6.16]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
// CHECK: 4: [B7.3]([B4.3])
@@ -800,23 +818,24 @@ const C &bar3(bool coin) {
// CHECK: Succs (1): B4
// CHECK: [B6]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B6.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B6.2], [B6.3], class B)
// CHECK: 2: [B6.1] (BindTemporary)
-// CHECK: 3: [B6.2].operator A
-// CHECK: 4: [B6.2]
-// CHECK: 5: [B6.4] (ImplicitCastExpr, UserDefinedConversion, class A)
-// CHECK: 6: [B6.5] (BindTemporary)
-// CHECK: 7: [B6.6] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 8: [B6.7]
-// WARNINGS: 9: [B6.8] (CXXConstructExpr, class A)
-// ANALYZER: 9: [B6.8] (CXXConstructExpr, [B6.10], [B6.13], [B6.14], class A)
-// CHECK: 10: [B6.9] (BindTemporary)
-// CHECK: 11: A([B6.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
-// CHECK: 12: [B6.11] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 13: [B6.12]
-// WARNINGS: 14: [B6.13] (CXXConstructExpr, class A)
-// ANALYZER: 14: [B6.13] (CXXConstructExpr, [B6.15], [B4.3], class A)
-// CHECK: 15: [B6.14] (BindTemporary)
+// CHECK: 3: [B6.2]
+// CHECK: 4: [B6.3].operator A
+// CHECK: 5: [B6.3]
+// CHECK: 6: [B6.5] (ImplicitCastExpr, UserDefinedConversion, class A)
+// CHECK: 7: [B6.6] (BindTemporary)
+// CHECK: 8: [B6.7] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 9: [B6.8]
+// WARNINGS: 10: [B6.9] (CXXConstructExpr, class A)
+// ANALYZER: 10: [B6.9] (CXXConstructExpr, [B6.11], [B6.14], [B6.15], class A)
+// CHECK: 11: [B6.10] (BindTemporary)
+// CHECK: 12: A([B6.11]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
+// CHECK: 13: [B6.12] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 14: [B6.13]
+// WARNINGS: 15: [B6.14] (CXXConstructExpr, class A)
+// ANALYZER: 15: [B6.14] (CXXConstructExpr, [B6.16], [B4.3], class A)
+// CHECK: 16: [B6.15] (BindTemporary)
// CHECK: Preds (1): B7
// CHECK: Succs (1): B4
// CHECK: [B7]
@@ -824,12 +843,13 @@ const C &bar3(bool coin) {
// CHECK: 2: foo
// CHECK: 3: [B7.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
// WARNINGS: 4: B() (CXXConstructExpr, class B)
-// ANALYZER: 4: B() (CXXConstructExpr, [B7.5], class B)
+// ANALYZER: 4: B() (CXXConstructExpr, [B7.5], [B7.6], class B)
// CHECK: 5: [B7.4] (BindTemporary)
-// CHECK: 6: [B7.5].operator bool
-// CHECK: 7: [B7.5]
-// CHECK: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.8] ? ... : ...
+// CHECK: 6: [B7.5]
+// CHECK: 7: [B7.6].operator bool
+// CHECK: 8: [B7.6]
+// CHECK: 9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B7.9] ? ... : ...
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B5 B6
// CHECK: [B8]
@@ -843,7 +863,7 @@ const C &bar3(bool coin) {
// CHECK: Preds (1): B10
// CHECK: Succs (1): B7
// CHECK: [B10]
-// CHECK: 1: [B13.5] ? [B11.6] : [B12.15]
+// CHECK: 1: [B13.6] ? [B11.6] : [B12.16]
// CHECK: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B10.2]
// CHECK: 4: const A &a = B() ? A() : A(B());
@@ -863,33 +883,35 @@ const C &bar3(bool coin) {
// CHECK: Succs (1): B10
// CHECK: [B12]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B12.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B12.2], [B12.3], class B)
// CHECK: 2: [B12.1] (BindTemporary)
-// CHECK: 3: [B12.2].operator A
-// CHECK: 4: [B12.2]
-// CHECK: 5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, class A)
-// CHECK: 6: [B12.5] (BindTemporary)
-// CHECK: 7: [B12.6] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 8: [B12.7]
-// WARNINGS: 9: [B12.8] (CXXConstructExpr, class A)
-// ANALYZER: 9: [B12.8] (CXXConstructExpr, [B12.10], [B12.13], [B12.14], class A)
-// CHECK: 10: [B12.9] (BindTemporary)
-// CHECK: 11: A([B12.10]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
-// CHECK: 12: [B12.11] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 13: [B12.12]
-// WARNINGS: 14: [B12.13] (CXXConstructExpr, class A)
-// ANALYZER: 14: [B12.13] (CXXConstructExpr, [B10.3], class A)
-// CHECK: 15: [B12.14] (BindTemporary)
+// CHECK: 3: [B12.2]
+// CHECK: 4: [B12.3].operator A
+// CHECK: 5: [B12.3]
+// CHECK: 6: [B12.5] (ImplicitCastExpr, UserDefinedConversion, class A)
+// CHECK: 7: [B12.6] (BindTemporary)
+// CHECK: 8: [B12.7] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 9: [B12.8]
+// WARNINGS: 10: [B12.9] (CXXConstructExpr, class A)
+// ANALYZER: 10: [B12.9] (CXXConstructExpr, [B12.11], [B12.14], [B12.15], class A)
+// CHECK: 11: [B12.10] (BindTemporary)
+// CHECK: 12: A([B12.11]) (CXXFunctionalCastExpr, ConstructorConversion, class A)
+// CHECK: 13: [B12.12] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 14: [B12.13]
+// WARNINGS: 15: [B12.14] (CXXConstructExpr, class A)
+// ANALYZER: 15: [B12.14] (CXXConstructExpr, [B10.3], class A)
+// CHECK: 16: [B12.15] (BindTemporary)
// CHECK: Preds (1): B13
// CHECK: Succs (1): B10
// CHECK: [B13]
// WARNINGS: 1: B() (CXXConstructExpr, class B)
-// ANALYZER: 1: B() (CXXConstructExpr, [B13.2], class B)
+// ANALYZER: 1: B() (CXXConstructExpr, [B13.2], [B13.3], class B)
// CHECK: 2: [B13.1] (BindTemporary)
-// CHECK: 3: [B13.2].operator bool
-// CHECK: 4: [B13.2]
-// CHECK: 5: [B13.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B13.5] ? ... : ...
+// CHECK: 3: [B13.2]
+// CHECK: 4: [B13.3].operator bool
+// CHECK: 5: [B13.3]
+// CHECK: 6: [B13.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B13.6] ? ... : ...
// CHECK: Preds (1): B14
// CHECK: Succs (2): B11 B12
// CHECK: [B0 (EXIT)]
@@ -949,15 +971,11 @@ const C &bar3(bool coin) {
// ANALYZER-CXX98: 1: A() (CXXConstructExpr, [B7.2], [B7.3], class A)
// ANALYZER-CXX11: 1: A() (CXXConstructExpr, [B7.2], class A)
// CHECK: 2: [B7.1] (BindTemporary)
-// CXX98: 3: [B7.2].operator bool
-// CXX98: 4: [B7.2]
-// CXX98: 5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX98: T: [B7.5] ? ... : ...
-// CXX11: 3: [B7.2]
-// CXX11: 4: [B7.3].operator bool
-// CXX11: 5: [B7.3]
-// CXX11: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX11: T: [B7.6] ? ... : ...
+// CHECK: 3: [B7.2]
+// CHECK: 4: [B7.3].operator bool
+// CHECK: 5: [B7.3]
+// CHECK: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B7.6] ? ... : ...
// CHECK: Preds (1): B8
// CHECK: Succs (2): B5 B6
// CHECK: [B0 (EXIT)]
@@ -1017,15 +1035,11 @@ const C &bar3(bool coin) {
// ANALYZER-CXX98: 3: A() (CXXConstructExpr, [B7.4], class A)
// ANALYZER-CXX11: 3: A() (CXXConstructExpr, class A)
// CHECK: 4: [B7.3] (BindTemporary)
-// CXX98: 5: [B7.4].operator bool
-// CXX98: 6: [B7.4]
-// CXX98: 7: [B7.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX98: T: [B7.7] ? ... : ...
-// CXX11: 5: [B7.4]
-// CXX11: 6: [B7.5].operator bool
-// CXX11: 7: [B7.5]
-// CXX11: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX11: T: [B7.8] ? ... : ...
+// CHECK: 5: [B7.4]
+// CHECK: 6: [B7.5].operator bool
+// CHECK: 7: [B7.5]
+// CHECK: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B5 B6
// CHECK: [B8]
@@ -1069,15 +1083,11 @@ const C &bar3(bool coin) {
// ANALYZER-CXX98: 1: A() (CXXConstructExpr, [B12.2], [B12.3], class A)
// ANALYZER-CXX11: 1: A() (CXXConstructExpr, [B12.2], class A)
// CHECK: 2: [B12.1] (BindTemporary)
-// CXX98: 3: [B12.2].operator bool
-// CXX98: 4: [B12.2]
-// CXX98: 5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX98: T: [B12.5] ? ... : ...
-// CXX11: 3: [B12.2]
-// CXX11: 4: [B12.3].operator bool
-// CXX11: 5: [B12.3]
-// CXX11: 6: [B12.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CXX11: T: [B12.6] ? ... : ...
+// CHECK: 3: [B12.2]
+// CHECK: 4: [B12.3].operator bool
+// CHECK: 5: [B12.3]
+// CHECK: 6: [B12.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B12.6] ? ... : ...
// CHECK: Preds (1): B13
// CHECK: Succs (2): B10 B11
// CHECK: [B0 (EXIT)]
@@ -1177,15 +1187,16 @@ const C &bar3(bool coin) {
// CHECK: [B1]
// CHECK: 1: int a;
// WARNINGS: 2: A() (CXXConstructExpr, class A)
-// ANALYZER: 2: A() (CXXConstructExpr, [B1.3], class A)
+// ANALYZER: 2: A() (CXXConstructExpr, [B1.3], [B1.4], class A)
// CHECK: 3: [B1.2] (BindTemporary)
-// CHECK: 4: [B1.3].operator int
-// CHECK: 5: [B1.3]
-// CHECK: 6: [B1.5] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 7: a
-// CHECK: 8: [B1.7] = [B1.6]
-// CHECK: 9: ~A() (Temporary object destructor)
-// CHECK: 10: int b;
+// CHECK: 4: [B1.3]
+// CHECK: 5: [B1.4].operator int
+// CHECK: 6: [B1.4]
+// CHECK: 7: [B1.6] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 8: a
+// CHECK: 9: [B1.8] = [B1.7]
+// CHECK: 10: ~A() (Temporary object destructor)
+// CHECK: 11: int b;
// CHECK: Preds (1): B2
// CHECK: Succs (1): B0
// CHECK: [B0 (EXIT)]
@@ -1194,25 +1205,27 @@ const C &bar3(bool coin) {
// CHECK: Succs (1): B1
// CHECK: [B1]
// WARNINGS: 1: A() (CXXConstructExpr, class A)
-// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], class A)
+// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.3], class A)
// CHECK: 2: [B1.1] (BindTemporary)
-// CHECK: 3: [B1.2].operator int
-// CHECK: 4: [B1.2]
-// CHECK: 5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int)
-// WARNINGS: 7: B() (CXXConstructExpr, class B)
-// ANALYZER: 7: B() (CXXConstructExpr, [B1.8], class B)
-// CHECK: 8: [B1.7] (BindTemporary)
-// CHECK: 9: [B1.8].operator int
-// CHECK: 10: [B1.8]
-// CHECK: 11: [B1.10] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 12: int([B1.11]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK: 13: [B1.6] + [B1.12]
-// CHECK: 14: a([B1.13]) (Member initializer)
-// CHECK: 15: ~B() (Temporary object destructor)
-// CHECK: 16: ~A() (Temporary object destructor)
-// CHECK: 17: /*implicit*/(int)0
-// CHECK: 18: b([B1.17]) (Member initializer)
+// CHECK: 3: [B1.2]
+// CHECK: 4: [B1.3].operator int
+// CHECK: 5: [B1.3]
+// CHECK: 6: [B1.5] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 7: int([B1.6]) (CXXFunctionalCastExpr, NoOp, int)
+// WARNINGS: 8: B() (CXXConstructExpr, class B)
+// ANALYZER: 8: B() (CXXConstructExpr, [B1.9], [B1.10], class B)
+// CHECK: 9: [B1.8] (BindTemporary)
+// CHECK: 10: [B1.9]
+// CHECK: 11: [B1.10].operator int
+// CHECK: 12: [B1.10]
+// CHECK: 13: [B1.12] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 14: int([B1.13]) (CXXFunctionalCastExpr, NoOp, int)
+// CHECK: 15: [B1.7] + [B1.14]
+// CHECK: 16: a([B1.15]) (Member initializer)
+// CHECK: 17: ~B() (Temporary object destructor)
+// CHECK: 18: ~A() (Temporary object destructor)
+// CHECK: 19: /*implicit*/(int)0
+// CHECK: 20: b([B1.19]) (Member initializer)
// CHECK: Preds (1): B2
// CHECK: Succs (1): B0
// CHECK: [B0 (EXIT)]
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp Fri Jul 27 10:13:18 2018
@@ -35,7 +35,7 @@ template<typename R> struct ConstexprMem
constexpr R F() const { return 0; }
};
constexpr int d = ConstexprMember<int>().F(); // ok
-constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonLiteral' cannot be used in a constant expression}}
+constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}}
template<typename ...P> struct ConstexprCtor {
constexpr ConstexprCtor(P...) {}
Modified: cfe/trunk/test/CodeGenCXX/stack-reuse-miscompile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/stack-reuse-miscompile.cpp?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/stack-reuse-miscompile.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/stack-reuse-miscompile.cpp Fri Jul 27 10:13:18 2018
@@ -1,8 +1,4 @@
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -disable-llvm-passes -std=c++03 %s -o - | FileCheck %s
-
-// This test should not to generate llvm.lifetime.start/llvm.lifetime.end for
-// f function because all temporary objects in this function are used for the
-// final result
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -O1 -disable-llvm-passes -std=c++03 %s -o - | FileCheck %s --implicit-check-not=llvm.lifetime
class S {
char *ptr;
@@ -23,14 +19,36 @@ public:
const char * f(S s)
{
+// It's essential that the lifetimes of all three T temporaries here are
+// overlapping. They must all remain alive through the call to str().
+//
// CHECK: [[T1:%.*]] = alloca %class.T, align 4
// CHECK: [[T2:%.*]] = alloca %class.T, align 4
// CHECK: [[T3:%.*]] = alloca %class.T, align 4
-// CHECK: [[T4:%.*]] = call %class.T* @_ZN1TC1EPKc(%class.T* [[T1]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0))
-// CHECK: [[T5:%.*]] = call %class.T* @_ZN1TC1E1S(%class.T* [[T2]], [2 x i32] %{{.*}})
-// CHECK: call void @_ZNK1T6concatERKS_(%class.T* sret [[T3]], %class.T* [[T1]], %class.T* dereferenceable(16) [[T2]])
-// CHECK: [[T6:%.*]] = call i8* @_ZNK1T3strEv(%class.T* [[T3]])
+//
+// FIXME: We could defer starting the lifetime of the return object of concat
+// until the call.
+// CHECK: [[T1i8:%.*]] = bitcast %class.T* [[T1]] to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T1i8]])
+//
+// CHECK: [[T2i8:%.*]] = bitcast %class.T* [[T2]] to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T2i8]])
+// CHECK: [[T4:%.*]] = call %class.T* @_ZN1TC1EPKc(%class.T* [[T2]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0))
+//
+// CHECK: [[T3i8:%.*]] = bitcast %class.T* [[T3]] to i8*
+// CHECK: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[T3i8]])
+// CHECK: [[T5:%.*]] = call %class.T* @_ZN1TC1E1S(%class.T* [[T3]], [2 x i32] %{{.*}})
+//
+// CHECK: call void @_ZNK1T6concatERKS_(%class.T* sret [[T1]], %class.T* [[T2]], %class.T* dereferenceable(16) [[T3]])
+// CHECK: [[T6:%.*]] = call i8* @_ZNK1T3strEv(%class.T* [[T1]])
+//
+// CHECK: call void @llvm.lifetime.end.p0i8(
+// CHECK: call void @llvm.lifetime.end.p0i8(
+// CHECK: call void @llvm.lifetime.end.p0i8(
// CHECK: ret i8* [[T6]]
return T("[").concat(T(s)).str();
}
+
+// CHECK: declare {{.*}}llvm.lifetime.start
+// CHECK: declare {{.*}}llvm.lifetime.end
Modified: cfe/trunk/test/CodeGenObjCXX/literals.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/literals.mm?rev=338135&r1=338134&r2=338135&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/literals.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/literals.mm Fri Jul 27 10:13:18 2018
@@ -18,19 +18,25 @@ struct Y {
void test_array() {
// CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*
// CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]
+ // CHECK: [[TMPX:%[a-zA-Z0-9.]+]] = alloca %
+ // CHECK: [[TMPY:%[a-zA-Z0-9.]+]] = alloca %
// Initializing first element
// CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]])
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
- // CHECK-NEXT: call void @_ZN1XC1Ev
+ // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPX]] to i8*
+ // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
+ // CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]])
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
// CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]])
// CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
// Initializing the second element
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
- // CHECK-NEXT: invoke void @_ZN1YC1Ev
+ // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPY]] to i8*
+ // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
+ // CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]])
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
// CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]])
// CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
@@ -75,14 +81,14 @@ void test_array_instantiation() {
// CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]])
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
- // CHECK-NEXT: call void @_ZN1XC1Ev
+ // CHECK: call void @_ZN1XC1Ev
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
// CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]])
// CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
// Initializing the second element
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
- // CHECK-NEXT: invoke void @_ZN1YC1Ev
+ // CHECK: invoke void @_ZN1YC1Ev
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
// CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]])
// CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
More information about the cfe-commits
mailing list