Skip to content

Commit 9ac1246

Browse files
committed
Fix bug in reflection template arguments.
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.
1 parent 7ae90d8 commit 9ac1246

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
lines changed

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8844,25 +8844,13 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue(
88448844
static ExprResult
88458845
BuildExpressionFromReflection(Sema &S, const ReflectionValue &R,
88468846
SourceLocation Loc) {
8847-
switch (R.getKind()) {
8848-
case ReflectionValue::RK_null:
8849-
return CXXReflectExpr::Create(S.Context, Loc, Loc);
8850-
case ReflectionValue::RK_type:
8851-
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsType());
8852-
case ReflectionValue::RK_expr_result:
8853-
return CXXReflectExpr::Create(S.Context, Loc, R.getAsExprResult());
8854-
case ReflectionValue::RK_declaration:
8855-
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsDecl());
8856-
case ReflectionValue::RK_template:
8857-
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsTemplate());
8858-
case ReflectionValue::RK_namespace:
8859-
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsNamespace());
8860-
case ReflectionValue::RK_base_specifier:
8861-
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsBaseSpecifier());
8862-
case ReflectionValue::RK_data_member_spec:
8863-
return CXXReflectExpr::Create(S.Context, Loc, Loc, R.getAsDataMemberSpec());
8864-
}
8865-
llvm_unreachable("unknown reflection kind");
8847+
ConstantExpr *CE =
8848+
ConstantExpr::CreateEmpty(S.Context, ConstantResultStorageKind::APValue);
8849+
CE->setType(S.Context.MetaInfoTy);
8850+
CE->setValueKind(VK_PRValue);
8851+
CE->SetResult(APValue(R.getKind(), R.getOpaqueValue()), S.Context);
8852+
8853+
return CE;
88668854
}
88678855

88688856
/// Construct a new expression that refers to the given reflection template

libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,31 @@ static_assert(rvfirst == std::meta::reflect_value(std::make_pair(1, true)));
277277
static_assert([:rvfirst:].first == 1);
278278
} // namespace values_from_objects
279279

280+
// =======================================
281+
// bb_clang_p2996_issue_67_regression_test
282+
// =======================================
283+
284+
namespace bb_clang_p2996_issue_67_regression_test {
285+
template<class T> struct TCls {};
286+
287+
template <std::size_t Count, std::meta::info... Rs>
288+
struct Cls
289+
{
290+
static void fn()
291+
{
292+
[] <auto... Idxs> (std::index_sequence<Idxs...>) consteval {
293+
(void) (Rs...[Idxs], ...);
294+
}(std::make_index_sequence<Count>());
295+
}
296+
};
297+
298+
void odr_use()
299+
{
300+
Cls<1, std::meta::reflect_value(0)>::fn();
301+
}
302+
} // namespace bb_clang_p2996_issue_67_regression_test
303+
304+
280305
int main() {
281306
// RUN: grep "call-lambda-value: 1" %t.stdout
282307
extract<void(*)(int)>(

0 commit comments

Comments
 (0)