Force instantiation of Decls used as substitute arguments.

Fixes #147.
This commit is contained in:
Dan Katz
2025-06-01 10:17:50 -04:00
parent 601fb61a65
commit 8013a76182
2 changed files with 21 additions and 4 deletions

View File

@@ -2777,8 +2777,8 @@ static bool CanActAsTemplateArg(const APValue &RV) {
llvm_unreachable("unknown reflection kind");
}
static TemplateArgument TArgFromReflection(ASTContext &C, EvalFn Evaluator,
const APValue &RV,
static TemplateArgument TArgFromReflection(ASTContext &C, MetaActions &Meta,
EvalFn Evaluator, const APValue &RV,
SourceLocation Loc) {
switch (RV.getReflectionKind()) {
case ReflectionKind::Type:
@@ -2801,6 +2801,9 @@ static TemplateArgument TArgFromReflection(ASTContext &C, EvalFn Evaluator,
if (Decl->isInvalidDecl())
break;
if (!Meta.EnsureInstantiated(Decl, SourceRange(Loc, Loc)))
return TemplateArgument();
QualType QT = desugarType(Decl->getType(), /*UnwrapAliases=*/ false,
/*DropCV=*/false, /*DropRefs=*/true);
@@ -2883,7 +2886,7 @@ bool substitute(APValue &Result, ASTContext &C, MetaActions &Meta,
Diagnoser(Range.getBegin(), diag::metafn_cannot_be_arg)
<< DescriptionOf(Unwrapped) << 1 << Range;
TemplateArgument TArg = TArgFromReflection(C, Evaluator, Unwrapped,
TemplateArgument TArg = TArgFromReflection(C, Meta, Evaluator, Unwrapped,
Range.getBegin());
if (TArg.isNull())
return true;
@@ -6114,7 +6117,7 @@ bool reflect_invoke(APValue &Result, ASTContext &C, MetaActions &Meta,
return Diagnoser(Range.getBegin(), diag::metafn_cannot_be_arg)
<< DescriptionOf(RV) << 1 << Range;
TemplateArgument TArg = TArgFromReflection(C, Evaluator, RV,
TemplateArgument TArg = TArgFromReflection(C, Meta, Evaluator, RV,
Range.getBegin());
if (TArg.isNull())
return true;

View File

@@ -462,6 +462,20 @@ template <auto &V> static constexpr auto &Value = V;
static_assert([:substitute(^^Value, {members_of(^^Cls, ctx)[0]}):] == 11);
} // namespace non_type_ref_regression_test
// ========================================
// bb_clang_p2996_issue_147_regression_test
// ========================================
namespace bb_clang_p2996_issue_147_regression_test {
template<int V> constexpr int my_int = V;
template<int S> struct test {};
constexpr auto r = substitute(^^test, {
substitute(^^my_int, {std::meta::reflect_constant(0)})
});
} // namespace bb_clang_p2996_issue_147_regression_test
// ===============
// wording_example
// ===============