r183092 - Fix a couple of bugs where jump diagnostics would not notice that a variable

Richard Smith richard-llvm at metafoo.co.uk
Sun Jun 2 18:05:37 PDT 2013


Author: rsmith
Date: Sun Jun  2 20:05:37 2013
New Revision: 183092

URL: http://llvm.org/viewvc/llvm-project?rev=183092&view=rev
Log:
Fix a couple of bugs where jump diagnostics would not notice that a variable
has an initializer.

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=183092&r1=183091&r2=183092&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
+++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Sun Jun  2 20:05:37 2013
@@ -172,10 +172,6 @@ static ScopePair GetDiagForGotoScopeDecl
       if (EWC)
         Init = EWC->getSubExpr();
 
-      // FIXME: Why are we looking through reference initialization?
-      //        This causes us to incorrectly accept invalid code such as:
-      //   struct S { int n; };
-      //   int f() { goto x; S &&s = S(); x: return x.n; }
       const MaterializeTemporaryExpr *M = NULL;
       Init = Init->findMaterializedTemporary(M);
 
@@ -184,7 +180,7 @@ static ScopePair GetDiagForGotoScopeDecl
       Init = Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
 
       QualType QT = Init->getType();
-      if (QT.isNull() || !CommaLHSs.empty())
+      if (QT.isNull())
         return ScopePair(diag::note_protected_by_variable_init, 0);
 
       const Type *T = QT.getTypePtr();
@@ -203,7 +199,11 @@ static ScopePair GetDiagForGotoScopeDecl
 
       if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(Init)) {
         const CXXConstructorDecl *ctor = cce->getConstructor();
-        if (ctor->isTrivial() && ctor->isDefaultConstructor()) {
+        // For a variable declared without an initializer, we will have
+        // call-style initialization and the initializer will be the
+        // CXXConstructExpr with no intervening nodes.
+        if (ctor->isTrivial() && ctor->isDefaultConstructor() &&
+            VD->getInit() == Init && VD->getInitStyle() == VarDecl::CallInit) {
           if (OutDiag)
             InDiag = diag::note_protected_by_variable_nontriv_destructor;
           else if (!Record->isPOD())

Modified: cfe/trunk/test/SemaCXX/scope-check.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/scope-check.cpp?rev=183092&r1=183091&r2=183092&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/scope-check.cpp (original)
+++ cfe/trunk/test/SemaCXX/scope-check.cpp Sun Jun  2 20:05:37 2013
@@ -276,6 +276,27 @@ namespace test15 {
 }
 
 namespace test16 {
+  struct S { int n; };
+  int f() {
+    goto x; // expected-error {{goto into protected scope}}
+    const S &s = S(); // expected-note {{jump bypasses variable initialization}}
+x:  return s.n;
+  }
+}
+
+#if __cplusplus >= 201103L
+namespace test17 {
+  struct S { int get(); private: int n; };
+  int f() {
+    goto x; // expected-error {{goto into protected scope}}
+    S s = {}; // expected-note {{jump bypasses variable initialization}}
+x:  return s.get();
+  }
+}
+#endif
+
+// This test must be last, because the error prohibits further jump diagnostics.
+namespace testInvalid {
 Invalid inv; // expected-error {{unknown type name}}
 // Make sure this doesn't assert.
 void fn()





More information about the cfe-commits mailing list