Skip to content

Commit

Permalink
Fix crashes with substitute of reference-type non-type template param…
Browse files Browse the repository at this point in the history
…eters.
  • Loading branch information
katzdm committed Oct 25, 2024
1 parent 45749e4 commit 4992006
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 12 deletions.
17 changes: 5 additions & 12 deletions clang/lib/AST/ExprConstantMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2457,6 +2457,8 @@ static TemplateArgument TArgFromReflection(ASTContext &C, EvalFn Evaluator,
}
case ReflectionKind::Declaration: {
ValueDecl *Decl = RV.getReflectedDecl();
if (Decl->isInvalidDecl())
break;

// Don't worry about the cost of creating an expression here: The template
// substitution machinery will otherwise create one from the argument
Expand All @@ -2466,15 +2468,6 @@ static TemplateArgument TArgFromReflection(ASTContext &C, EvalFn Evaluator,
false, Loc, Decl->getType(), VK_LValue, Decl,
nullptr);

if (Decl->getType()->isIntegralOrEnumerationType()) {
APValue R;
if (!Evaluator(R, Synthesized, true))
break;

return TemplateArgument(C, R.getInt(),
Synthesized->getType().getCanonicalType());
}

return TemplateArgument(Synthesized);
}
case ReflectionKind::Template:
Expand Down Expand Up @@ -2537,7 +2530,7 @@ bool can_substitute(APValue &Result, ASTContext &C, MetaActions &Meta,
TemplateArgument TArg = TArgFromReflection(C, Evaluator, Unwrapped,
Range.getBegin());
if (TArg.isNull())
llvm_unreachable("could not form template argument?");
return true;
TArgs.push_back(TArg);
}
}
Expand Down Expand Up @@ -2600,7 +2593,7 @@ bool substitute(APValue &Result, ASTContext &C, MetaActions &Meta,
TemplateArgument TArg = TArgFromReflection(C, Evaluator, Unwrapped,
Range.getBegin());
if (TArg.isNull())
llvm_unreachable("could not form template argument?");
return true;
TArgs.push_back(TArg);
}
}
Expand Down Expand Up @@ -4801,7 +4794,7 @@ bool reflect_invoke(APValue &Result, ASTContext &C, MetaActions &Meta,
TemplateArgument TArg = TArgFromReflection(C, Evaluator, RV,
Range.getBegin());
if (TArg.isNull())
llvm_unreachable("could not form template argument?");
return true;
TArgs.push_back(TArg);
}

Expand Down
10 changes: 10 additions & 0 deletions libcxx/test/std/experimental/reflection/substitute.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,5 +436,15 @@ static_assert(substitute(^^member_pointer, {^^Test, ^^int}) !=
substitute(^^member_pointer, {^^Test, ^^float}));
} // namespace bb_clang_p2996_issue_101_regression_test

// ============================
// non_type_ref_regression_test
// ============================

namespace non_type_ref_regression_test {
class Cls { static constexpr int priv = 11; };
template <auto &V> static constexpr auto &Value = V;

static_assert([:substitute(^^Value, {members_of(^^Cls)[0]}):] == 11);
} // namespace non_type_ref_regression_test

int main() { }

0 comments on commit 4992006

Please sign in to comment.