On Wed, Feb 25, 2026 at 10:17:03AM -0500, Marek Polacek wrote:
> On Wed, Feb 25, 2026 at 11:24:50PM +1100, Nathaniel Shead wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu. This isn't really a
> > bugfix but I think it's a simple improvement, OK for trunk?
>
> I think since it only affects code with REFLECTION_TYPE_P types, it's
> OK for GCC 16 too.
>
> > Or otherwise for GCC 17?
> >
> > -- >8 --
> >
> > This adds another case to static_assert to print a helpful diagnostic
> > when comparing reflections. This makes it easier to see what's gone
> > wrong when doing 'static_assert(some_query(^^a) == some_query(^^b));'
> > by decomposing the resulting resulting reflection.
>
> Nice!
>
> > There's no need to do this decomposition in cases where both operands
> > are already in their lowest form however, e.g. for cases like
> > static_assert(^^int == ^^double).
> >
> > gcc/cp/ChangeLog:
> >
> > * constexpr.cc (diagnose_failing_condition): Also decompose
> > comparisons of reflections.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/reflect/diag5.C: New test.
>
> Patch looks good (but please wait for Jason's OK). I'm noticing that for
>
> struct S {
> void fn();
> };
> static_assert(&[:^^S::fn:] != &S::fn);
>
> we say "the comparison reduces to '(1 == 0)'" but that has nothing
> to do with this patch.
Thanks. Actually I noticed I'd forgotten to update the testcase before
committing (needed to escape special characters), here's an updated
version that just does the reflection differences:
-- >8 --
Subject: [PATCH] c++/reflection: Improve static_assert diagnostics when
comparing reflections
This adds another case to static_assert to print a helpful diagnostic
when comparing reflections. This makes it easier to see what's gone
wrong when doing 'static_assert(some_query(^^a) == some_query(^^b));'
by decomposing the resulting resulting reflection.
gcc/cp/ChangeLog:
* constexpr.cc (diagnose_failing_condition): Also decompose
comparisons of reflections.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/diag5.C: New test.
Signed-off-by: Nathaniel Shead <[email protected]>
---
gcc/cp/constexpr.cc | 3 ++-
gcc/testsuite/g++.dg/reflect/diag5.C | 9 +++++++++
2 files changed, 11 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/reflect/diag5.C
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 44e6b352d9a..afd8d5731a1 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -3107,7 +3107,8 @@ diagnose_failing_condition (tree bad, location_t cloc,
bool show_expr_p,
else if (maybe_diagnose_standard_trait (cloc, bad))
;
else if (COMPARISON_CLASS_P (bad)
- && ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0))))
+ && (ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))
+ || REFLECTION_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))))
{
tree op0 = fold_operand (TREE_OPERAND (bad, 0), ctx);
tree op1 = fold_operand (TREE_OPERAND (bad, 1), ctx);
diff --git a/gcc/testsuite/g++.dg/reflect/diag5.C
b/gcc/testsuite/g++.dg/reflect/diag5.C
new file mode 100644
index 00000000000..1f808364ce8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/diag5.C
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+// Test that we decompose reflections in static_asserts, where applicable.
+
+constexpr auto a = ^^int;
+consteval auto b() { return ^^double; }
+
+static_assert(a == b()); // { dg-error "static assertion failed" }
+// { dg-message "the comparison reduces to '\\\(\\^\\^int ==
\\^\\^double\\\)'" "" { target *-*-* } .-1 }
--
2.51.0