r226067 - Fix crash-on-invalid and name lookup when recovering from ~X::X() typo.

Richard Smith richard-llvm at metafoo.co.uk
Wed Jan 14 16:48:53 PST 2015


Author: rsmith
Date: Wed Jan 14 18:48:52 2015
New Revision: 226067

URL: http://llvm.org/viewvc/llvm-project?rev=226067&view=rev
Log:
Fix crash-on-invalid and name lookup when recovering from ~X::X() typo.

Modified:
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/Parser/cxx-class.cpp
    cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=226067&r1=226066&r2=226067&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Jan 14 18:48:52 2015
@@ -4916,7 +4916,8 @@ void Parser::ParseDirectDeclarator(Decla
     }
 
     if (D.getCXXScopeSpec().isValid()) {
-      if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
+      if (Actions.ShouldEnterDeclaratorScope(getCurScope(),
+                                             D.getCXXScopeSpec()))
         // Change the declaration context for name lookup, until this function
         // is exited (and the declarator has been parsed).
         DeclScopeObj.EnterDeclaratorScope();
@@ -4968,6 +4969,7 @@ void Parser::ParseDirectDeclarator(Decla
         AllowConstructorName = (D.getContext() == Declarator::MemberContext);
 
       SourceLocation TemplateKWLoc;
+      bool HadScope = D.getCXXScopeSpec().isValid();
       if (ParseUnqualifiedId(D.getCXXScopeSpec(),
                              /*EnteringContext=*/true,
                              /*AllowDestructorName=*/true,
@@ -4981,6 +4983,13 @@ void Parser::ParseDirectDeclarator(Decla
         D.SetIdentifier(nullptr, Tok.getLocation());
         D.setInvalidType(true);
       } else {
+        // ParseUnqualifiedId might have parsed a scope specifier during error
+        // recovery. If it did so, enter that scope.
+        if (!HadScope && D.getCXXScopeSpec().isValid() &&
+            Actions.ShouldEnterDeclaratorScope(getCurScope(),
+                                               D.getCXXScopeSpec()))
+          DeclScopeObj.EnterDeclaratorScope();
+
         // Parsed the unqualified-id; update range information and move along.
         if (D.getSourceRange().getBegin().isInvalid())
           D.SetRangeBegin(D.getName().getSourceRange().getBegin());

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=226067&r1=226066&r2=226067&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Jan 14 18:48:52 2015
@@ -2504,6 +2504,7 @@ 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 (SS.isSet()) {
         AnnotateScopeToken(SS, /*NewAnnotation*/true);
@@ -2520,6 +2521,10 @@ bool Parser::ParseUnqualifiedId(CXXScope
       Diag(TildeLoc, diag::err_destructor_tilde_scope)
         << FixItHint::CreateRemoval(TildeLoc)
         << FixItHint::CreateInsertion(Tok.getLocation(), "~");
+
+      // Temporarily enter the scope for the rest of this function.
+      if (Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
+        DeclScopeObj.EnterDeclaratorScope();
     }
 
     // Parse the class-name (or template-name in a simple-template-id).

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=226067&r1=226066&r2=226067&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Jan 14 18:48:52 2015
@@ -113,6 +113,9 @@ ParsedType Sema::getDestructorName(Sourc
   bool isDependent = false;
   bool LookInScope = false;
 
+  if (SS.isInvalid())
+    return ParsedType();
+
   // If we have an object type, it's because we are in a
   // pseudo-destructor-expression or a member access expression, and
   // we know what type we're looking for.

Modified: cfe/trunk/test/Parser/cxx-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-class.cpp?rev=226067&r1=226066&r2=226067&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-class.cpp (original)
+++ cfe/trunk/test/Parser/cxx-class.cpp Wed Jan 14 18:48:52 2015
@@ -140,8 +140,8 @@ namespace CtorErrors {
 }
 
 namespace DtorErrors {
-  struct A { ~A(); } a;
-  ~A::A() {} // expected-error {{'~' in destructor name should be after nested name specifier}} expected-note {{previous}}
+  struct A { ~A(); int n; } a;
+  ~A::A() { n = 0; } // expected-error {{'~' in destructor name should be after nested name specifier}} expected-note {{previous}}
   A::~A() {} // expected-error {{redefinition}}
 
   struct B { ~B(); } *b;
@@ -151,6 +151,12 @@ namespace DtorErrors {
     a.~A::A(); // expected-error {{'~' in destructor name should be after nested name specifier}}
     b->~DtorErrors::~B::B(); // expected-error {{'~' in destructor name should be after nested name specifier}}
   }
+
+  struct C; // expected-note {{forward decl}}
+  ~C::C() {} // expected-error {{incomplete}} expected-error {{'~' in destructor name should be after nested name specifier}}
+
+  struct D { struct X {}; ~D() throw(X); };
+  ~D::D() throw(X) {} // expected-error {{'~' in destructor name should be after nested name specifier}}
 }
 
 namespace BadFriend {

Modified: cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp?rev=226067&r1=226066&r2=226067&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp (original)
+++ cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp Wed Jan 14 18:48:52 2015
@@ -17,7 +17,7 @@ namespace PR6161 {
   {
     static locale::id id; // expected-error{{use of undeclared identifier}}
   };
-  numpunct<char>::~numpunct(); // expected-error{{expected the class name after '~' to name a destructor}}
+  numpunct<char>::~numpunct();
 }
 
 namespace PR12331 {





More information about the cfe-commits mailing list