On 9/1/23 20:00, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --

When verify_constant complains, it's pretty terse.  Consider

   void test ()
   {
     constexpr int i = 42;
     constexpr const int *p = &i;
   }

where it says "'& i' is not a constant expression".  OK, but why?

With this patch, we say:

b.C:5:28: error: '& i' is not a constant expression
     5 |   constexpr const int *p = &i;
       |                            ^~
b.C:5:28: note: pointer to 'i' is not a constant expression
b.C:4:17: note: address of non-static constexpr variable 'i' may differ on each 
invocation of the enclosing function; add 'static' to give it a constant address
     4 |   constexpr int i = 42;
       |                 ^
       |                 static

which brings g++ on par with clang++.

gcc/cp/ChangeLog:

        * constexpr.cc (verify_constant_explain_r): New.
        (verify_constant): Call it.

gcc/testsuite/ChangeLog:

        * g++.dg/diagnostic/constexpr3.C: New test.
---
  gcc/cp/constexpr.cc                          | 56 +++++++++++++++++++-
  gcc/testsuite/g++.dg/diagnostic/constexpr3.C | 32 +++++++++++
  2 files changed, 87 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/diagnostic/constexpr3.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 8bd5c4a47f8..6d5aed82377 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -3381,6 +3381,54 @@ ok:
      }
  }
+/* *TP was not deemed constant by reduced_constant_expression_p. Explain
+   why and suggest what could be done about it.  */
+
+static tree
+verify_constant_explain_r (tree *tp, int *, void *)
+{
+  bool ref_p = false;

I think you'll want something along the lines of

  /* No need to look into types or unevaluated operands.  */
  if (TYPE_P (init) || unevaluated_p (code))
    {
      *walk_subtrees = false;
      return NULL_TREE;
    }

(from find_uninit_fields_r).

OK with that change.

Jason

Reply via email to