r227581 - Follow-up to r217302 and r227555: Don't crash on inline ~A::A() if A is an int.

Nico Weber nicolasweber at gmx.de
Fri Jan 30 08:53:11 PST 2015


Author: nico
Date: Fri Jan 30 10:53:11 2015
New Revision: 227581

URL: http://llvm.org/viewvc/llvm-project?rev=227581&view=rev
Log:
Follow-up to r217302 and r227555: Don't crash on inline ~A::A() if A is an int.

Even with r227555, this still crashed:

  struct S {
    int A;
    ~A::A() {}
  };

That's because ParseOptionalCXXScopeSpecifier()'s call to
ActOnCXXNestedNameSpecifier() doesn't mark the scope spec as invalid if sema
thought it's a good idea to fixit-correct "::" to ":".  For the diagnostic
improvement done in r217302, we never want :: to be interpreted as :, so fix
this by setting ColonSacred to false temporarily.

Found by SLi's bot.

Modified:
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/test/Parser/cxx-class.cpp

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=227581&r1=227580&r2=227581&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri Jan 30 10:53:11 2015
@@ -2509,7 +2509,13 @@ bool Parser::ParseUnqualifiedId(CXXScope
 
     // If the user wrote ~T::T, correct it to T::~T.
     DeclaratorScopeObj DeclScopeObj(*this, SS);
-    if (!TemplateSpecified && NextToken().is(tok::coloncolon)) {
+    if (!TemplateSpecified && //!ColonIsSacred &&
+        NextToken().is(tok::coloncolon)) {
+      // Don't let ParseOptionalCXXScopeSpecifier() "correct"
+      // `int A; struct { ~A::A(); };` to `int A; struct { ~A:A(); };`,
+      // it will confuse this recovery logic.
+      ColonProtectionRAIIObject ColonRAII(*this, false);
+
       if (SS.isSet()) {
         AnnotateScopeToken(SS, /*NewAnnotation*/true);
         SS.clear();

Modified: cfe/trunk/test/Parser/cxx-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-class.cpp?rev=227581&r1=227580&r2=227581&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-class.cpp (original)
+++ cfe/trunk/test/Parser/cxx-class.cpp Fri Jan 30 10:53:11 2015
@@ -159,6 +159,21 @@ namespace DtorErrors {
   ~D::D() throw(X) {} // expected-error {{'~' in destructor name should be after nested name specifier}}
 
   ~Undeclared::Undeclared() {} // expected-error {{use of undeclared identifier 'Undeclared'}} expected-error {{'~' in destructor name should be after nested name specifier}}
+
+  struct S {
+    // For another struct's destructor, emit the same diagnostic like for
+    // A::~A() in addition to the "~ in the wrong place" one.
+    ~A::A() {} // expected-error {{'~' in destructor name should be after nested name specifier}} expected-error {{non-friend class member '~A' cannot have a qualified name}}
+    A::~A() {} // expected-error {{non-friend class member '~A' cannot have a qualified name}}
+
+    // An inline destructor with a redundant class name should also get the
+    // same diagnostic as S::~S.
+    ~S::S() {} // expected-error {{'~' in destructor name should be after nested name specifier}} expected-error {{extra qualification on member '~S'}}
+
+    // This just shouldn't crash.
+    int I; // expected-note {{declared here}}
+    ~I::I() {} // expected-error {{'I' is not a class, namespace, or enumeration}} expected-error {{'~' in destructor name should be after nested name specifier}}
+  };
 }
 
 namespace BadFriend {





More information about the cfe-commits mailing list