diff options
author | Alex Orlov <aorlov@accesssoftek.com> | 2021-08-10 19:20:50 +0400 |
---|---|---|
committer | Alex Orlov <aorlov@accesssoftek.com> | 2021-08-10 19:20:50 +0400 |
commit | 638dcea010cfc280f428d0cc13f4aa8578a1d69d (patch) | |
tree | 937ca2a1d8486d7cdbe1a4ab9d363761417c6613 /clang/lib/Parse/ParseDecl.cpp | |
parent | e260e10c4a21784c146c94a2a14b7e78b09a9cf7 (diff) | |
download | llvm-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.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; } |