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