This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ Patch] [PR c++/88146] do not crash synthesizing inherited ctor(...)


On Dec 28, 2018, Alexandre Oliva <aoliva@redhat.com> wrote:

> I guess I still need to
> fill in other gaps to in my knowledge to try and make sense of it.

Done.

> diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c

Here's a patch based on your suggestion.


[PR88146] do not instantiate constexpr if not manifestly const

This is another approach at fixing the g++.dg/cpp0x/inh-ctor32.C test
failures on targets that have non-void return values for cdtors: only
instantiate constexpr functions for expressions that are potentially
constant evaluated.

Alas, this exposed a latent problem elsewhere: braced initializer
lists underwent check_narrowing when simplified to non-lists, but that
did not signal maybe_constant_value the potentially constant evaluated
constant that all direct members of braced initializer lists have, so
after the change above we'd no longer initialize constexpr functions
that per P0859 we ought to.

cpp2a/constexpr-init1.C, taken directly from P0859, flagged the
regression.  While looking into it, I realized it was fragile: it
could have passed even if we flagged the error we should flag for the
construct that we are supposed to accept.  So, I split it out, to
catch too-aggressive constexpr instantiation as much as the too-lax
instantiation the original testcase flagged after the first part of
the change.

Regstrapped on x86_64- and i686-linux-gnu.  Ok to install?


for  gcc/cp/ChangeLog

	PR c++/88146
	* constexpr.c (cxx_eval_outermost_constant_expr): Only
	instantiate constexpr fns for manifestly const eval.
	* typeck2.c (check_narrowing): Test for maybe constant value
	with manifestly const eval.

for  gcc/testsuite/ChangeLog

	PR c++/88146
	* g++.dg/cpp2a/constexpr-inst1a.C: Split out of...
	* g++.dg/cpp2a/constexpr-inst1.C: ... this.
---
 gcc/cp/constexpr.c                            |    3 ++-
 gcc/cp/typeck2.c                              |    6 +++++-
 gcc/testsuite/g++.dg/cpp2a/constexpr-inst1.C  |    3 ---
 gcc/testsuite/g++.dg/cpp2a/constexpr-inst1a.C |    9 +++++++++
 4 files changed, 16 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-inst1a.C

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index cea414d33def..88bee7aa1fed 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5076,7 +5076,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
 	r = TARGET_EXPR_INITIAL (r);
     }
 
-  instantiate_constexpr_fns (r);
+  if (ctx.manifestly_const_eval)
+    instantiate_constexpr_fns (r);
   r = cxx_eval_constant_expression (&ctx, r,
 				    false, &non_constant_p, &overflow_p);
 
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index cc9bf02439b6..ae194d519395 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -918,7 +918,11 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain, bool const_only)
       return ok;
     }
 
-  init = maybe_constant_value (init);
+  /* Immediate subexpressions in BRACED_ENCLOSED_INITIALIZERs are
+     potentially constant evaluated.  Without manifestly_const_eval,
+     we won't instantiate constexpr functions that we must
+     instantiate.  */
+  init = maybe_constant_value (init, NULL_TREE, /*manifestly_const_eval=*/true);
 
   /* If we were asked to only check constants, return early.  */
   if (const_only && !TREE_CONSTANT (init))
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1.C
index 1016bec9d3e1..34863de3cf84 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1.C
@@ -2,12 +2,9 @@
 // { dg-do compile { target c++14 } }
 
 template<typename T> constexpr int f() { return T::value; } // { dg-error "int" }
-template<bool B, typename T> void g(decltype(B ? f<T>() : 0));
-template<bool B, typename T> void g(...);
 template<bool B, typename T> void h(decltype(int{B ? f<T>() : 0}));
 template<bool B, typename T> void h(...);
 void x() {
-  g<false, int>(0); // OK, B ? f<T>() : 0 is not potentially constant evaluated
   h<false, int>(0); // error, instantiates f<int> even though B evaluates to false and
                     // list-initialization of int from int cannot be narrowing
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1a.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1a.C
new file mode 100644
index 000000000000..1c068595e374
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-inst1a.C
@@ -0,0 +1,9 @@
+// Testcase from P0859
+// { dg-do compile { target c++14 } }
+
+template<typename T> constexpr int f() { return T::value; }
+template<bool B, typename T> void g(decltype(B ? f<T>() : 0));
+template<bool B, typename T> void g(...);
+void x() {
+  g<false, int>(0); // OK, B ? f<T>() : 0 is not potentially constant evaluated
+}


-- 
Alexandre Oliva, freedom fighter   https://FSFLA.org/blogs/lxo
Be the change, be Free!         FSF Latin America board member
GNU Toolchain Engineer                Free Software Evangelist
Hay que enGNUrecerse, pero sin perder la terGNUra jamás-GNUChe


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]