r229449 - For variables with dependent type, don't crash on `var->::new` or `var->__super`

Nico Weber nicolasweber at gmx.de
Mon Feb 16 14:32:46 PST 2015


Author: nico
Date: Mon Feb 16 16:32:46 2015
New Revision: 229449

URL: http://llvm.org/viewvc/llvm-project?rev=229449&view=rev
Log:
For variables with dependent type, don't crash on `var->::new` or `var->__super`

ParsePostfixExpressionSuffix() for '->' (or '.') postfixes first calls
ActOnStartCXXMemberReference() to inform sema that a member reference is about
to start, and that function lets the parser know if sema thinks that the
base expression's type could allow a pseudo destructor from a semantic point of
view (for example, if the the base expression has a dependent type).

ParsePostfixExpressionSuffix() then calls ParseOptionalCXXScopeSpecifier() and
passes MayBePseudoDestructor on to that function, expecting the function to
set it to false if a pseudo destructor is impossible from a syntactic point of
view (due to a lack of '~' sigil).  However, ParseOptionalCXXScopeSpecifier()
had early-outs for ::new and __super, so MayBePseudoDestructor stayed true,
so we tried to parse a pseudo dtor, and then became confused since we couldn't
find a '~'.  Move the snippet in ParseOptionalCXXScopeSpecifier() that sets
MayBePseudoDestructor to false above the early exits.

Parts of this found by SLi's bot.

Modified:
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/test/SemaCXX/MicrosoftSuper.cpp
    cfe/trunk/test/SemaCXX/new-delete.cpp

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=229449&r1=229448&r2=229449&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Feb 16 16:32:46 2015
@@ -194,6 +194,7 @@ bool Parser::ParseOptionalCXXScopeSpecif
 
   if (Tok.is(tok::annot_cxxscope)) {
     assert(!LastII && "want last identifier but have already annotated scope");
+    assert(!MayBePseudoDestructor && "unexpected annot_cxxscope");
     Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
                                                  Tok.getAnnotationRange(),
                                                  SS);
@@ -208,6 +209,13 @@ bool Parser::ParseOptionalCXXScopeSpecif
     SS = TemplateId->SS;
   }
 
+  // Has to happen before any "return false"s in this function.
+  bool CheckForDestructor = false;
+  if (MayBePseudoDestructor && *MayBePseudoDestructor) {
+    CheckForDestructor = true;
+    *MayBePseudoDestructor = false;
+  }
+
   if (LastII)
     *LastII = nullptr;
 
@@ -244,12 +252,6 @@ bool Parser::ParseOptionalCXXScopeSpecif
     return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS);
   }
 
-  bool CheckForDestructor = false;
-  if (MayBePseudoDestructor && *MayBePseudoDestructor) {
-    CheckForDestructor = true;
-    *MayBePseudoDestructor = false;
-  }
-
   if (!HasScopeSpecifier &&
       (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))) {
     DeclSpec DS(AttrFactory);

Modified: cfe/trunk/test/SemaCXX/MicrosoftSuper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftSuper.cpp?rev=229449&r1=229448&r2=229449&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftSuper.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftSuper.cpp Mon Feb 16 16:32:46 2015
@@ -147,3 +147,12 @@ void instantiate() {
   DerivedFromTemplateParameter<Base1> t;
   t.foo();
 }
+
+namespace {
+struct B { int a; };
+template <class C>
+struct A : B {
+  // Don't crash on dependent_type_var '->' '__super'
+  void f() { int a = this->__super::a; }
+};
+}

Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=229449&r1=229448&r2=229449&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Mon Feb 16 16:32:46 2015
@@ -524,3 +524,11 @@ namespace PR18544 {
 
 // PR19968
 inline void* operator new(); // expected-error {{'operator new' must have at least one parameter}}
+
+namespace {
+template <class C>
+struct A {
+  void f() { this->::new; } // expected-error {{expected unqualified-id}}
+  void g() { this->::delete; } // expected-error {{expected unqualified-id}}
+};
+}





More information about the cfe-commits mailing list