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.
llvm-svn: 227581
This commit is contained in:
parent
655b59854f
commit
f9e37be2d6
@ -2509,7 +2509,13 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
|
||||
|
||||
// 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();
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user