public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Alexandre Oliva <aoliva@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: Christophe Lyon <christophe.lyon@linaro.org>,
	       gcc-patches List <gcc-patches@gcc.gnu.org>
Subject: Re: [C++ Patch] [PR c++/88146] do not crash synthesizing inherited ctor(...)
Date: Sat, 29 Dec 2018 06:40:00 -0000	[thread overview]
Message-ID: <orbm55giz5.fsf@lxoliva.fsfla.org> (raw)
In-Reply-To: <orsgyhh251.fsf@lxoliva.fsfla.org> (Alexandre Oliva's message of	"Fri, 28 Dec 2018 17:39:22 -0200")

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

  reply	other threads:[~2018-12-29  2:33 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-07  0:23 Alexandre Oliva
2018-12-14 20:14 ` Alexandre Oliva
2018-12-14 20:42 ` Jason Merrill
2018-12-14 21:41   ` Jason Merrill
2018-12-14 22:34     ` Alexandre Oliva
2018-12-14 22:44       ` Jason Merrill
2018-12-14 23:05         ` Alexandre Oliva
2018-12-15 22:11           ` Jason Merrill
2018-12-19 14:36             ` Christophe Lyon
2018-12-19 18:49               ` Alexandre Oliva
2018-12-19 18:52                 ` Jakub Jelinek
2018-12-20  0:04               ` Alexandre Oliva
2018-12-20 16:00                 ` Christophe Lyon
2018-12-20 16:18                 ` Jason Merrill
2018-12-28 22:53                   ` Alexandre Oliva
2018-12-29  6:40                     ` Alexandre Oliva [this message]
2018-12-29 13:33                       ` Jakub Jelinek
2019-01-04 18:55                       ` Jason Merrill
2019-01-17  4:12                         ` Alexandre Oliva
2018-12-29 10:28                     ` Alexandre Oliva

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=orbm55giz5.fsf@lxoliva.fsfla.org \
    --to=aoliva@redhat.com \
    --cc=christophe.lyon@linaro.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).