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