Skip to content

Commit

Permalink
Fix bug in reflection template arguments.
Browse files Browse the repository at this point in the history
Rather than representing a reflection non-type template argument as a
CXXReflectExpr, represent it using a ConstantExpr. Some reflections
aren't representable as a CXXReflectExpr (e.g., results of
reflect_value), leading to errant diagnostics for otherwise legal
substitutions.

Closes issue llvm#67.
  • Loading branch information
katzdm committed Jul 1, 2024
1 parent 7ae90d8 commit 9ac1246
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 19 deletions.
26 changes: 7 additions & 19 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8844,25 +8844,13 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue(
static ExprResult
BuildExpressionFromReflection(Sema &S, const ReflectionValue &R,
SourceLocation Loc) {
switch (R.getKind()) {
case ReflectionValue::RK_null:
return CXXReflectExpr::Create(S.Context, Loc, Loc);
case ReflectionValue::RK_type:
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsType());
case ReflectionValue::RK_expr_result:
return CXXReflectExpr::Create(S.Context, Loc, R.getAsExprResult());
case ReflectionValue::RK_declaration:
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsDecl());
case ReflectionValue::RK_template:
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsTemplate());
case ReflectionValue::RK_namespace:
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsNamespace());
case ReflectionValue::RK_base_specifier:
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsBaseSpecifier());
case ReflectionValue::RK_data_member_spec:
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsDataMemberSpec());
}
llvm_unreachable("unknown reflection kind");
ConstantExpr *CE =
ConstantExpr::CreateEmpty(S.Context, ConstantResultStorageKind::APValue);
CE->setType(S.Context.MetaInfoTy);
CE->setValueKind(VK_PRValue);
CE->SetResult(APValue(R.getKind(), R.getOpaqueValue()), S.Context);

return CE;
}

/// Construct a new expression that refers to the given reflection template
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,31 @@ static_assert(rvfirst == std::meta::reflect_value(std::make_pair(1, true)));
static_assert([:rvfirst:].first == 1);
} // namespace values_from_objects

// =======================================
// bb_clang_p2996_issue_67_regression_test
// =======================================

namespace bb_clang_p2996_issue_67_regression_test {
template<class T> struct TCls {};

template <std::size_t Count, std::meta::info... Rs>
struct Cls
{
static void fn()
{
[] <auto... Idxs> (std::index_sequence<Idxs...>) consteval {
(void) (Rs...[Idxs], ...);
}(std::make_index_sequence<Count>());
}
};

void odr_use()
{
Cls<1, std::meta::reflect_value(0)>::fn();
}
} // namespace bb_clang_p2996_issue_67_regression_test


int main() {
// RUN: grep "call-lambda-value: 1" %t.stdout
extract<void(*)(int)>(
Expand Down

0 comments on commit 9ac1246

Please sign in to comment.