Skip to content

Commit 9bf4e54

Browse files
authored
[clang] Represent array refs as TemplateArgument::Declaration (#80050)
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.
1 parent 74bf0b1 commit 9bf4e54

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7417,9 +7417,9 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
74177417
if (ArgResult.isInvalid())
74187418
return ExprError();
74197419

7420-
// Prior to C++20, enforce restrictions on possible template argument
7421-
// values.
7422-
if (!getLangOpts().CPlusPlus20 && Value.isLValue()) {
7420+
if (Value.isLValue()) {
7421+
APValue::LValueBase Base = Value.getLValueBase();
7422+
auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
74237423
// For a non-type template-parameter of pointer or reference type,
74247424
// the value of the constant expression shall not refer to
74257425
assert(ParamType->isPointerType() || ParamType->isReferenceType() ||
@@ -7428,33 +7428,37 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
74287428
// -- a string literal
74297429
// -- the result of a typeid expression, or
74307430
// -- a predefined __func__ variable
7431-
APValue::LValueBase Base = Value.getLValueBase();
7432-
auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
74337431
if (Base &&
74347432
(!VD ||
74357433
isa<LifetimeExtendedTemporaryDecl, UnnamedGlobalConstantDecl>(VD))) {
74367434
Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref)
74377435
<< Arg->getSourceRange();
74387436
return ExprError();
74397437
}
7440-
// -- a subobject [until C++20]
7441-
if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 &&
7442-
VD && VD->getType()->isArrayType() &&
7438+
7439+
if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 && VD &&
7440+
VD->getType()->isArrayType() &&
74437441
Value.getLValuePath()[0].getAsArrayIndex() == 0 &&
74447442
!Value.isLValueOnePastTheEnd() && ParamType->isPointerType()) {
7445-
// Per defect report (no number yet):
7446-
// ... other than a pointer to the first element of a complete array
7447-
// object.
7448-
} else if (!Value.hasLValuePath() || Value.getLValuePath().size() ||
7449-
Value.isLValueOnePastTheEnd()) {
7450-
Diag(StartLoc, diag::err_non_type_template_arg_subobject)
7451-
<< Value.getAsString(Context, ParamType);
7452-
return ExprError();
7443+
SugaredConverted = TemplateArgument(VD, ParamType);
7444+
CanonicalConverted = TemplateArgument(
7445+
cast<ValueDecl>(VD->getCanonicalDecl()), CanonParamType);
7446+
return ArgResult.get();
7447+
}
7448+
7449+
// -- a subobject [until C++20]
7450+
if (!getLangOpts().CPlusPlus20) {
7451+
if (!Value.hasLValuePath() || Value.getLValuePath().size() ||
7452+
Value.isLValueOnePastTheEnd()) {
7453+
Diag(StartLoc, diag::err_non_type_template_arg_subobject)
7454+
<< Value.getAsString(Context, ParamType);
7455+
return ExprError();
7456+
}
7457+
assert((VD || !ParamType->isReferenceType()) &&
7458+
"null reference should not be a constant expression");
7459+
assert((!VD || !ParamType->isNullPtrType()) &&
7460+
"non-null value of type nullptr_t?");
74537461
}
7454-
assert((VD || !ParamType->isReferenceType()) &&
7455-
"null reference should not be a constant expression");
7456-
assert((!VD || !ParamType->isNullPtrType()) &&
7457-
"non-null value of type nullptr_t?");
74587462
}
74597463

74607464
if (Value.isAddrLabelDiff())

clang/test/CoverageMapping/templates.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,16 @@ int main() {
1919
func<bool>(true);
2020
return 0;
2121
}
22+
23+
namespace structural_value_crash {
24+
template <int* p>
25+
void tpl_fn() {
26+
(void)p;
27+
}
28+
29+
int arr[] = {1, 2, 3};
30+
31+
void test() {
32+
tpl_fn<arr>();
33+
}
34+
}

0 commit comments

Comments
 (0)