[clang] [clang] Represent array refs as `TemplateArgument::Declaration` (PR #80050)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 30 12:04:14 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Andrey Ali Khan Bolshakov (bolshakov-a)
<details>
<summary>Changes</summary>
This returns (probably temporarily) array-referring NTTP behavior to which was prior to #<!-- -->78041 because ~~I'm fed up~~ have no time to fix regressions.
---
Full diff: https://github.com/llvm/llvm-project/pull/80050.diff
1 Files Affected:
- (modified) clang/lib/Sema/SemaTemplate.cpp (+24-20)
``````````diff
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3f33ecb89502e..9e8d058041f04 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7417,9 +7417,9 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (ArgResult.isInvalid())
return ExprError();
- // Prior to C++20, enforce restrictions on possible template argument
- // values.
- if (!getLangOpts().CPlusPlus20 && Value.isLValue()) {
+ if (Value.isLValue()) {
+ APValue::LValueBase Base = Value.getLValueBase();
+ auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
// For a non-type template-parameter of pointer or reference type,
// the value of the constant expression shall not refer to
assert(ParamType->isPointerType() || ParamType->isReferenceType() ||
@@ -7428,8 +7428,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// -- a string literal
// -- the result of a typeid expression, or
// -- a predefined __func__ variable
- APValue::LValueBase Base = Value.getLValueBase();
- auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
if (Base &&
(!VD ||
isa<LifetimeExtendedTemporaryDecl, UnnamedGlobalConstantDecl>(VD))) {
@@ -7437,24 +7435,30 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
<< Arg->getSourceRange();
return ExprError();
}
- // -- a subobject [until C++20]
- if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 &&
- VD && VD->getType()->isArrayType() &&
+
+ if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 && VD &&
+ VD->getType()->isArrayType() &&
Value.getLValuePath()[0].getAsArrayIndex() == 0 &&
!Value.isLValueOnePastTheEnd() && ParamType->isPointerType()) {
- // Per defect report (no number yet):
- // ... other than a pointer to the first element of a complete array
- // object.
- } else if (!Value.hasLValuePath() || Value.getLValuePath().size() ||
- Value.isLValueOnePastTheEnd()) {
- Diag(StartLoc, diag::err_non_type_template_arg_subobject)
- << Value.getAsString(Context, ParamType);
- return ExprError();
+ SugaredConverted = TemplateArgument(VD, ParamType);
+ CanonicalConverted = TemplateArgument(
+ cast<ValueDecl>(VD->getCanonicalDecl()), CanonParamType);
+ return ArgResult.get();
+ }
+
+ // -- a subobject [until C++20]
+ if (!getLangOpts().CPlusPlus20) {
+ if (!Value.hasLValuePath() || Value.getLValuePath().size() ||
+ Value.isLValueOnePastTheEnd()) {
+ Diag(StartLoc, diag::err_non_type_template_arg_subobject)
+ << Value.getAsString(Context, ParamType);
+ return ExprError();
+ }
+ assert((VD || !ParamType->isReferenceType()) &&
+ "null reference should not be a constant expression");
+ assert((!VD || !ParamType->isNullPtrType()) &&
+ "non-null value of type nullptr_t?");
}
- assert((VD || !ParamType->isReferenceType()) &&
- "null reference should not be a constant expression");
- assert((!VD || !ParamType->isNullPtrType()) &&
- "non-null value of type nullptr_t?");
}
if (Value.isAddrLabelDiff())
``````````
</details>
https://github.com/llvm/llvm-project/pull/80050
More information about the cfe-commits
mailing list