diff options
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 9393235..2b19ade 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3091,6 +3091,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, return true; }; + // Turn off usual access checking for template specializations and + // instantiations. + bool IsTemplateSpecOrInst = + (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || + TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); + switch (Tok.getKind()) { default: DoneWithDeclSpec: @@ -3261,6 +3267,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isConstructorDeclarator(/*Unqualified*/ false)) goto DoneWithDeclSpec; + // C++20 [temp.spec] 13.9/6. + // This disables the access checking rules for function template explicit + // instantiation and explicit specialization: + // - `return type`. + SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst); + ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(), getCurScope(), &SS, false, false, nullptr, @@ -3268,6 +3280,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, /*WantNontrivialTypeSourceInfo=*/true, isClassTemplateDeductionContext(DSContext)); + if (IsTemplateSpecOrInst) + SAC.done(); + // If the referenced identifier is not a type, then this declspec is // erroneous: We already checked about that it has no type specifier, and // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the @@ -3377,10 +3392,24 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // In C++, check to see if this is a scope specifier like foo::bar::, if // so handle it as such. This is important for ctor parsing. if (getLangOpts().CPlusPlus) { - if (TryAnnotateCXXScopeToken(EnteringContext)) { + // C++20 [temp.spec] 13.9/6. + // This disables the access checking rules for function template + // explicit instantiation and explicit specialization: + // - `return type`. + SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst); + + const bool Success = TryAnnotateCXXScopeToken(EnteringContext); + + if (IsTemplateSpecOrInst) + SAC.done(); + + if (Success) { + if (IsTemplateSpecOrInst) + SAC.redelay(); DS.SetTypeSpecError(); goto DoneWithDeclSpec; } + if (!Tok.is(tok::identifier)) continue; } |