Don't crash on 'decltype(auto)::'. Rather than treating it as a meaningless

nested-name-specifier (as the standard appears to require), treat it as the
type specifier 'decltype(auto)' followed by a nested-name-specifier starting
with '::'.

llvm-svn: 294506
This commit is contained in:
Richard Smith 2017-02-08 19:58:48 +00:00
parent 0674fe39e5
commit 3f846bd9fe
2 changed files with 16 additions and 1 deletions

View File

@ -216,7 +216,10 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
SourceLocation CCLoc;
if (!TryConsumeToken(tok::coloncolon, CCLoc)) {
// Work around a standard defect: 'decltype(auto)::' is not a
// nested-name-specifier.
if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto ||
!TryConsumeToken(tok::coloncolon, CCLoc)) {
AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);
return false;
}

View File

@ -385,6 +385,18 @@ namespace MemberTemplatesWithDeduction {
}
}
namespace NNS {
int n;
decltype(auto) i();
decltype(n) j();
struct X {
// We resolve a wording bug here: 'decltype(auto)::' should not be parsed
// as a nested-name-specifier.
friend decltype(auto) ::NNS::i();
friend decltype(n) ::NNS::j(); // expected-error {{not a class}}
};
}
namespace CurrentInstantiation {
// PR16875
template<typename T> struct S {