https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86524

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Similarly, when changing:
-  static_assert (!foo (&x, &x));
+  constexpr bool y = foo (&x, &x);
+  static_assert (!y);

I think the problem is that finish_static_assert evaluates the condition using
fold_non_dependent_expr -> maybe_constant_value and that results in ctx->quiet
being true while evaluating the expression (it wants to diagnose non-constant
expression only later).  But we have also:

  /* Don't fold __builtin_constant_p within a constexpr function.  */
  bool bi_const_p = (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P);

  /* If we aren't requiring a constant expression, defer __builtin_constant_p
     in a constexpr function until we have values for the parameters.  */
  if (bi_const_p
      && ctx->quiet
      && current_function_decl
      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
    {
      *non_constant_p = true;
      return t;
    }

which means if ctx->quiet is true, we don't try at all to evaluate the builtin.
That is reasonable while parsing the constexpr functions of cp_folding it, but
we don't have a way right now to differentiate between that and the
finish_static_assert which is try as hard as possible to evaluate it to a
constant, just don't complain if that fails.  So, do we need another constexpr
context flag for this, or should we e.g. try to fold the __builtin_constant_p
in any case and only set *non_constant_p if it evaluates to false, or something
similar?

Reply via email to