mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-12 09:41:26 +00:00
Fix crash-on-invalid and name lookup when recovering from ~X::X() typo.
llvm-svn: 226067
This commit is contained in:
parent
8ffce23cda
commit
64e033f9c4
@ -4916,7 +4916,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||
}
|
||||
|
||||
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(Declarator &D) {
|
||||
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(Declarator &D) {
|
||||
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());
|
||||
|
@ -2504,6 +2504,7 @@ 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 (SS.isSet()) {
|
||||
AnnotateScopeToken(SS, /*NewAnnotation*/true);
|
||||
@ -2520,6 +2521,10 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
|
||||
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).
|
||||
|
@ -113,6 +113,9 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
|
||||
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.
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user