C++ PATCH for c++/87372, __func__ constexpr evaluation

Marek Polacek polacek@redhat.com
Fri Sep 21 04:05:00 GMT 2018


The patch for P0595R1 - is_constant_evaluated had this hunk:

@@ -5279,7 +5315,9 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant)
   else if (CONSTANT_CLASS_P (t) && allow_non_constant)
     /* No evaluation needed.  */;
   else
-    t = cxx_eval_outermost_constant_expr (t, allow_non_constant, false, decl);
+    t = cxx_eval_outermost_constant_expr (t, allow_non_constant,
+                     !allow_non_constant,
+                     pretend_const_required, decl);
   if (TREE_CODE (t) == TARGET_EXPR)
     {
       tree init = TARGET_EXPR_INITIAL (t);

the false -> !allow_non_constant change means that when calling
cxx_constant_init strict will be true because cxx_constant_init does not allow
non constants.  That means that for VAR_DECLs such as __func__ we'll call
decl_really_constant_value instead of decl_constant_value.  But only the latter
can evaluate __func__ to "foo()".

Jakub, was there a specific reason for this change?  Changing it back still
regtests cleanly and the attached test compiles again.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-09-20  Marek Polacek  <polacek@redhat.com>

	PR c++/87372 - __func__ constexpr evaluation.
	* constexpr.c (maybe_constant_init_1): Pass false for strict down to
	cxx_eval_outermost_constant_expr.

	* g++.dg/cpp1y/func_constexpr2.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index fdea769faa9..6436b2f832d 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -5361,7 +5361,7 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
     /* No evaluation needed.  */;
   else
     t = cxx_eval_outermost_constant_expr (t, allow_non_constant,
-					  !allow_non_constant,
+					  /*strict*/false,
 					  pretend_const_required, decl);
   if (TREE_CODE (t) == TARGET_EXPR)
     {
diff --git gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C
index e69de29bb2d..b1576e64960 100644
--- gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C
+++ gcc/testsuite/g++.dg/cpp1y/func_constexpr2.C
@@ -0,0 +1,21 @@
+// PR c++/87372
+// { dg-do compile { target c++14 } }
+
+constexpr int
+foo (char const *s)
+{
+  int i = 0;
+  while (s[i])
+    ++i;
+  return i;
+}
+
+constexpr int
+bar ()
+{
+  constexpr int l = foo (__PRETTY_FUNCTION__);
+  constexpr int l2 = foo (__FUNCTION__);
+  constexpr int l3 = foo (__func__);
+  return l + l2 + l3;
+}
+static_assert (bar () == 25, "");



More information about the Gcc-patches mailing list