diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index 1cf48a75ef90..a5f4e52ac01a 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -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; diff --git a/libcxx/test/std/experimental/reflection/substitute.verify.cpp b/libcxx/test/std/experimental/reflection/substitute.verify.cpp index d01d17bbdb2d..1c20529b2f19 100644 --- a/libcxx/test/std/experimental/reflection/substitute.verify.cpp +++ b/libcxx/test/std/experimental/reflection/substitute.verify.cpp @@ -462,6 +462,20 @@ template 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 constexpr int my_int = V; +template 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 // ===============