aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorAlex Orlov <aorlov@accesssoftek.com>2021-08-10 19:20:50 +0400
committerAlex Orlov <aorlov@accesssoftek.com>2021-08-10 19:20:50 +0400
commit638dcea010cfc280f428d0cc13f4aa8578a1d69d (patch)
tree937ca2a1d8486d7cdbe1a4ab9d363761417c6613 /clang/lib/Parse/ParseDecl.cpp
parente260e10c4a21784c146c94a2a14b7e78b09a9cf7 (diff)
downloadllvm-638dcea010cfc280f428d0cc13f4aa8578a1d69d.zip
llvm-638dcea010cfc280f428d0cc13f4aa8578a1d69d.tar.gz
llvm-638dcea010cfc280f428d0cc13f4aa8578a1d69d.tar.bz2
[clang] Implement P0692R1 from C++20 (access checking on specializations and instantiations)
This patch implements paper P0692R1 from the C++20 standard. Disable usual access checking rules to template argument names in a declaration of partial specializations, explicit instantiation or explicit specialization (C++20 13.7.5/10, 13.9.1/6). Fixes: https://llvm.org/PR37424 This patch also implements option *A* from this paper P0692R1 from the C++20 standard. This patch follows the @rsmith suggestion from D78404. Reviewed By: krisb Differential Revision: https://reviews.llvm.org/D92024
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp31
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;
}