From: Nico Weber Date: Mon, 2 Feb 2015 05:33:50 +0000 (+0000) Subject: Follow-up to r217302: Don't crash on ~A::A in a postfix expr suffix followed by '<'. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f794b6635f799d719101ba05821c6c64cd167c2f;p=clang Follow-up to r217302: Don't crash on ~A::A in a postfix expr suffix followed by '<'. This used to crash, complaining "ObjectType and scope specifier cannot coexist": struct A { } b = b.~A::A ; The only other caller of ParseOptionalCXXScopeSpecifier() that passes in a non-empty ObjectType clears the ObjectType of the scope specifier comes back non-empty (see the tok::period case in Parser::ParsePostfixExpressionSuffix()), so do that here too. Found by SLi's bot. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@227781 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 506e13ac4b..10ae450fe8 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -2521,6 +2521,8 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, } if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, EnteringContext)) return true; + if (SS.isNotEmpty()) + ObjectType = ParsedType(); if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) || SS.isInvalid()) { Diag(TildeLoc, diag::err_destructor_tilde_scope); diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp index 077bd6f02c..215c941a46 100644 --- a/test/Parser/cxx-class.cpp +++ b/test/Parser/cxx-class.cpp @@ -174,6 +174,11 @@ namespace DtorErrors { 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}} }; + + struct T {}; + T t1 = t1.T::~T; // expected-error {{destructor name 'T' does not refer to a template}} expected-error {{expected '(' for function-style cast or type construction}} expected-error {{expected expression}} + // Emit the same diagnostic as for the previous case, plus something about ~. + T t2 = t2.~T::T; // expected-error {{'~' in destructor name should be after nested name specifier}} expected-error {{destructor name 'T' does not refer to a template}} expected-error {{expected '(' for function-style cast or type construction}} expected-error {{expected expression}} } namespace BadFriend {