[cfe-commits] r166863 - in /cfe/trunk: lib/Sema/JumpDiagnostics.cpp test/SemaCXX/scope-check.cpp

Rafael Espindola rafael.espindola at gmail.com
Fri Oct 26 20:06:02 PDT 2012


Author: rafael
Date: Fri Oct 26 22:06:02 2012
New Revision: 166863

URL: http://llvm.org/viewvc/llvm-project?rev=166863&view=rev
Log:
Revert r166855. I can reproduce the bootstrap failure and have a testcase
to reduce.

Modified:
    cfe/trunk/lib/Sema/JumpDiagnostics.cpp
    cfe/trunk/test/SemaCXX/scope-check.cpp

Modified: cfe/trunk/lib/Sema/JumpDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/JumpDiagnostics.cpp?rev=166863&r1=166862&r2=166863&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
+++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Fri Oct 26 22:06:02 2012
@@ -123,7 +123,7 @@
 /// diagnostic that should be emitted if control goes over it. If not, return 0.
 static ScopePair GetDiagForGotoScopeDecl(ASTContext &Context, const Decl *D) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    unsigned InDiag = 0;
+    unsigned InDiag = 0, OutDiag = 0;
     if (VD->getType()->isVariablyModifiedType())
       InDiag = diag::note_protected_by_vla;
 
@@ -164,49 +164,43 @@
       //   where it is in scope is ill-formed unless the variable has
       //   POD type and is declared without an initializer.
 
-      const Expr *Init = VD->getInit();
-      if (!Init)
-        return ScopePair(InDiag, 0);
-
-      const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init);
-      if (EWC)
-        Init = EWC->getSubExpr();
-
-      const MaterializeTemporaryExpr *M = NULL;
-      Init = Init->findMaterializedTemporary(M);
-
-      SmallVector<SubobjectAdjustment, 2> Adjustments;
-      Init = Init->skipRValueSubobjectAdjustments(Adjustments);
-
-      const Type *T = Init->getType().getTypePtr();
-      if (T->isArrayType())
-        T = T->getBaseElementTypeUnsafe();
-
-      const CXXRecordDecl *Record = T->getAsCXXRecordDecl();
-      if (!Record)
-        return ScopePair(diag::note_protected_by_variable_init, 0);
-
-      // If we need to call a non trivial destructor for this variable,
-      // record an out diagnostic.
-      unsigned OutDiag = 0;
-      if (!Record->hasTrivialDestructor() && !Init->isGLValue())
-        OutDiag = diag::note_exits_dtor;
-
-      if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(Init)) {
-        const CXXConstructorDecl *ctor = cce->getConstructor();
-        if (ctor->isTrivial() && ctor->isDefaultConstructor()) {
-          if (OutDiag)
-            InDiag = diag::note_protected_by_variable_nontriv_destructor;
-          else if (!Record->isPOD())
-            InDiag = diag::note_protected_by_variable_non_pod;
-          return ScopePair(InDiag, OutDiag);
+      if (const Expr *init = VD->getInit()) {
+        // We actually give variables of record type (or array thereof)
+        // an initializer even if that initializer only calls a trivial
+        // ctor.  Detect that case.
+        // FIXME: With generalized initializer lists, this may
+        // classify "X x{};" as having no initializer.
+        unsigned inDiagToUse = diag::note_protected_by_variable_init;
+
+        const CXXRecordDecl *record = 0;
+
+        if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(init)) {
+          const CXXConstructorDecl *ctor = cce->getConstructor();
+          record = ctor->getParent();
+
+          if (ctor->isTrivial() && ctor->isDefaultConstructor()) {
+            if (!record->hasTrivialDestructor())
+              inDiagToUse = diag::note_protected_by_variable_nontriv_destructor;
+            else if (!record->isPOD())
+              inDiagToUse = diag::note_protected_by_variable_non_pod;
+            else
+              inDiagToUse = 0;
+          }
+        } else if (VD->getType()->isArrayType()) {
+          record = VD->getType()->getBaseElementTypeUnsafe()
+                                ->getAsCXXRecordDecl();
         }
-      }
 
-      return ScopePair(diag::note_protected_by_variable_init, OutDiag);
-    }
+        if (inDiagToUse)
+          InDiag = inDiagToUse;
 
-    return ScopePair(InDiag, 0);
+        // Also object to indirect jumps which leave scopes with dtors.
+        if (record && !record->hasTrivialDestructor())
+          OutDiag = diag::note_exits_dtor;
+      }
+    }
+    
+    return ScopePair(InDiag, OutDiag);    
   }
 
   if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {

Modified: cfe/trunk/test/SemaCXX/scope-check.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/scope-check.cpp?rev=166863&r1=166862&r2=166863&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/scope-check.cpp (original)
+++ cfe/trunk/test/SemaCXX/scope-check.cpp Fri Oct 26 22:06:02 2012
@@ -202,61 +202,3 @@
     return 0;
   }
 }
-
-// pr13812
-namespace test11 {
-  struct C {
-    C(int x);
-    ~C();
-  };
-  void f(void **ip) {
-    static void *ips[] = { &&l0 };
-  l0:  // expected-note {{possible target of indirect goto}}
-    C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
-    goto *ip; // expected-error {{indirect goto might cross protected scopes}}
-  }
-}
-
-namespace test12 {
-  struct C {
-    C(int x);
-    ~C();
-  };
-  void f(void **ip) {
-    static void *ips[] = { &&l0 };
-    const C c0 = 17;
-  l0: // expected-note {{possible target of indirect goto}}
-    const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
-    const C &c2 = c0;
-    goto *ip; // expected-error {{indirect goto might cross protected scopes}}
-  }
-}
-
-namespace test13 {
-  struct C {
-    C(int x);
-    ~C();
-    int i;
-  };
-  void f(void **ip) {
-    static void *ips[] = { &&l0 };
-  l0: // expected-note {{possible target of indirect goto}}
-    const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
-    goto *ip;  // expected-error {{indirect goto might cross protected scopes}}
-  }
-}
-
-namespace test14 {
-  struct C {
-    C(int x);
-    ~C();
-    operator int&() const;
-  };
-  void f(void **ip) {
-    static void *ips[] = { &&l0 };
-  l0:
-    // no warning since the C temporary is destructed before the goto.
-    const int &c1 = C(1);
-    goto *ip;
-  }
-}





More information about the cfe-commits mailing list