wrapup_namespace_globals gives errors for code like
extern inline int i;
int &r = i; // odr-used inline variable is not defined
but because we mark consteval-only vars DECL_EXTERNAL, we also wrongly
emit the error for:
inline constexpr info value{};
static_assert(value == info{});
where value clearly is defined. This patch strenghtens the check to
also check !DECL_INITIAL. We can't only check DECL_THIS_EXTERN because
extern constexpr inline info v2{};
is OK.
PR c++/124770
gcc/cp/ChangeLog:
* decl.cc (wrapup_namespace_globals): Give the odr-used
inline variable error only when !DECL_INITIAL.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/init18.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
if (VAR_P (decl)
&& DECL_EXTERNAL (decl)
+ /* We mark consteval-only variables DECL_EXTERNAL, but
+ extern constexpr inline std::meta::info i{};
+ is a definition (the extern is redundant). */
+ && !DECL_INITIAL (decl)
&& DECL_INLINE_VAR_P (decl)
&& DECL_ODR_USED (decl))
error_at (DECL_SOURCE_LOCATION (decl),
--- /dev/null
+// PR c++/124770
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+using info = decltype(^^::);
+
+constexpr inline info v{};
+static_assert(v == info{});
+extern constexpr inline info v2{};
+static_assert(v2 == info{});
+constexpr inline info v3;
+static_assert(v3 == info{});
+
+extern constexpr inline info v4; // { dg-error "not a definition|consteval-only" }