Move detection of reference members binding to temporaries from building of
CXXCtorInitializers to the point where we perform the questionable lifetime
extension. This exposed a selection of false negatives in the warning.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183869 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index b678f91..a4bccac 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2461,6 +2461,7 @@
 {
   InitializedEntity Result;
   Result.Kind = EK_Base;
+  Result.Parent = 0;
   Result.Base = reinterpret_cast<uintptr_t>(Base);
   if (IsInheritedVirtualBase)
     Result.Base |= 0x01;
@@ -2553,6 +2554,7 @@
 }
 
 unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const {
+  assert(getParent() != this);
   unsigned Depth = getParent() ? getParent()->dumpImpl(OS) : 0;
   for (unsigned I = 0; I != Depth; ++I)
     OS << "`-";
@@ -5566,9 +5568,33 @@
       // entity's lifetime.
       const ValueDecl *ExtendingDecl =
           getDeclForTemporaryLifetimeExtension(Entity);
-      if (ExtendingDecl)
+      if (ExtendingDecl) {
         performLifetimeExtension(CurInit.get(), ExtendingDecl);
 
+        // Warn if a field lifetime-extends a temporary.
+        if (isa<FieldDecl>(ExtendingDecl)) {
+          bool IsSubobjectMember = false;
+          for (const InitializedEntity *Ent = Entity.getParent(); Ent;
+               Ent = Ent->getParent()) {
+            if (Ent->getKind() != InitializedEntity::EK_Base) {
+              IsSubobjectMember = true;
+              break;
+            }
+          }
+          S.Diag(CurInit.get()->getExprLoc(),
+                 diag::warn_bind_ref_member_to_temporary)
+            << ExtendingDecl << CurInit.get()->getSourceRange()
+            << IsSubobjectMember;
+          if (IsSubobjectMember)
+            S.Diag(ExtendingDecl->getLocation(),
+                   diag::note_ref_subobject_of_member_declared_here);
+          else
+            S.Diag(ExtendingDecl->getLocation(),
+                   diag::note_ref_or_ptr_member_declared_here)
+              << /*IsPointer*/false;
+        }
+      }
+
       // Materialize the temporary into memory.
       MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(
           Entity.getType().getNonReferenceType(), CurInit.get(),