[cfe-commits] r132218 - in /cfe/trunk: lib/Sema/JumpDiagnostics.cpp lib/Sema/SemaDecl.cpp test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp test/CXX/stmt.stmt/stmt.dcl/p3.cpp

Douglas Gregor dgregor at apple.com
Fri May 27 14:28:01 PDT 2011


Author: dgregor
Date: Fri May 27 16:28:00 2011
New Revision: 132218

URL: http://llvm.org/viewvc/llvm-project?rev=132218&view=rev
Log:
Clean up my changes to jump-diagnostic handling for local variables of
class type (or array thereof), eliminating some redundant checks
(thanks Eli!) and adding some tests where the behavior differs in
C++98/03 vs. C++0x.

Added:
    cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp
Modified:
    cfe/trunk/lib/Sema/JumpDiagnostics.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp

Modified: cfe/trunk/lib/Sema/JumpDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/JumpDiagnostics.cpp?rev=132218&r1=132217&r2=132218&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
+++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Fri May 27 16:28:00 2011
@@ -140,35 +140,33 @@
         //   a trivial default constructor and a trivial destructor, a 
         //   cv-qualified version of one of these types, or an array of one of
         //   the preceding types and is declared without an initializer (8.5).
-        if (VD->hasLocalStorage() && Context.getLangOptions().CPlusPlus) {
-          // Check whether this is a C++ class.
-          CXXRecordDecl *Record = T->getAsCXXRecordDecl();
-          
-          if (const Expr *Init = VD->getInit()) {
-            bool CallsTrivialConstructor = false;
-            if (Record) {
-              // FIXME: With generalized initializer lists, this may
-              // classify "X x{};" as having no initializer.
-              if (const CXXConstructExpr *Construct 
-                                          = dyn_cast<CXXConstructExpr>(Init))
-                if (const CXXConstructorDecl *Constructor
-                                                  = Construct->getConstructor())
-                  if (Constructor->isDefaultConstructor() &&
-                      ((Context.getLangOptions().CPlusPlus0x &&
-                        Record->hasTrivialDefaultConstructor()) ||
-                       (!Context.getLangOptions().CPlusPlus0x &&
-                        Record->isPOD())))
-                    CallsTrivialConstructor = true;
-            }
-            
-            if (!CallsTrivialConstructor)
-              InDiag = diag::note_protected_by_variable_init;
+        // Check whether this is a C++ class.
+        CXXRecordDecl *Record = T->getAsCXXRecordDecl();
+        
+        if (const Expr *Init = VD->getInit()) {
+          bool CallsTrivialConstructor = false;
+          if (Record) {
+            // FIXME: With generalized initializer lists, this may
+            // classify "X x{};" as having no initializer.
+            if (const CXXConstructExpr *Construct 
+                                        = dyn_cast<CXXConstructExpr>(Init))
+              if (const CXXConstructorDecl *Constructor
+                                                = Construct->getConstructor())
+                if (Constructor->isDefaultConstructor() &&
+                    ((Context.getLangOptions().CPlusPlus0x &&
+                      Record->hasTrivialDefaultConstructor()) ||
+                     (!Context.getLangOptions().CPlusPlus0x &&
+                      Record->isPOD())))
+                  CallsTrivialConstructor = true;
           }
           
-          // Note whether we have a class with a non-trivial destructor.
-          if (Record && !Record->hasTrivialDestructor())
-            OutDiag = diag::note_exits_dtor;
+          if (!CallsTrivialConstructor)
+            InDiag = diag::note_protected_by_variable_init;
         }
+        
+        // Note whether we have a class with a non-trivial destructor.
+        if (Record && !Record->hasTrivialDestructor())
+          OutDiag = diag::note_exits_dtor;
       }
     }
     

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=132218&r1=132217&r2=132218&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri May 27 16:28:00 2011
@@ -5646,7 +5646,7 @@
         if ((!getLangOptions().CPlusPlus0x && !CXXRecord->isPOD()) ||
             (getLangOptions().CPlusPlus0x &&
              (!CXXRecord->hasTrivialDefaultConstructor() ||
-              (!CXXRecord->hasTrivialDestructor()))))
+              !CXXRecord->hasTrivialDestructor())))
           getCurFunction()->setHasBranchProtectedScope();
       }
     }

Added: cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp?rev=132218&view=auto
==============================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp (added)
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp Fri May 27 16:28:00 2011
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// PR10034
+struct X {};
+
+void exx(X) {}
+
+int test_ptr10034(int argc, char **argv)
+{
+ if (argc > 3)
+   goto end;
+
+ X x;
+ X xs[16];
+ exx(x);
+
+ end:
+   if (argc > 1) {
+   for (int i = 0; i < argc; ++i)
+   {
+
+   }
+   }
+   return 0;
+}
+
+struct Y {
+  ~Y();
+};
+
+void f();
+void test_Y() {
+  goto end;
+  Y y;
+ end:
+  f();
+  goto inner;
+  {
+    Y y2;
+  inner:
+    f();    
+  }
+  return;
+}
+
+struct Z {
+  Z operator=(const Z&);
+};
+
+void test_Z() {
+  goto end;
+  Z z;
+ end:
+  return;
+}

Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp?rev=132218&r1=132217&r2=132218&view=diff
==============================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp (original)
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.dcl/p3.cpp Fri May 27 16:28:00 2011
@@ -1,12 +1,11 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
 
 // PR10034
 struct X {};
 
 void exx(X) {}
 
-int main(int argc, char **argv)
+int test_ptr10034(int argc, char **argv)
 {
  if (argc > 3)
    goto end;
@@ -24,3 +23,25 @@
    }
    return 0;
 }
+
+struct Y {
+  ~Y();
+};
+
+void test_Y() {
+  goto end; // expected-error{{goto into protected scope}}
+  Y y; // expected-note{{jump bypasses variable initialization}}
+ end:
+  return;
+}
+
+struct Z {
+  Z operator=(const Z&);
+};
+
+void test_Z() {
+  goto end; // expected-error{{goto into protected scope}}
+  Z z; // expected-note{{jump bypasses variable initialization}}
+ end:
+  return;
+}





More information about the cfe-commits mailing list