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.

> Signed-off-by: Nathaniel Shead <[email protected]>
> ---
>  gcc/cp/constexpr.cc                  | 10 +++++++---
>  gcc/testsuite/g++.dg/reflect/diag5.C |  9 +++++++++
>  2 files changed, 16 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/reflect/diag5.C
> 
> diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> index 44e6b352d9a..4169f571285 100644
> --- a/gcc/cp/constexpr.cc
> +++ b/gcc/cp/constexpr.cc
> @@ -3107,12 +3107,16 @@ 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);
> -      tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
> -      inform (cloc, "the comparison reduces to %qE", cond);
> +      if (op0 != TREE_OPERAND (bad, 0) || op1 != TREE_OPERAND (bad, 1))
> +     {
> +       tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
> +       inform (cloc, "the comparison reduces to %qE", cond);
> +     }
>      }
>    else if (show_expr_p)
>      inform (cloc, "%qE evaluates to false", bad);
> diff --git a/gcc/testsuite/g++.dg/reflect/diag5.C 
> b/gcc/testsuite/g++.dg/reflect/diag5.C
> new file mode 100644
> index 00000000000..44af952415d
> --- /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
> 

Marek

Reply via email to