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]

C++ PATCH for c++/84978, ICE with NRVO


We started crashing on this test with r258592 which added cp_get_callee_fndecl
in <case AGGR_INIT_EXPR> in cp_genericize_r.

This ICE apparently depends on whether we perform NRVO or not.  If the size of
S is <=16B we pass it in registers and it compiles fine.  But if the size of S
is >16B, then we pass in memory, and we NRV-optimize.  That means that
s.fn ();
is turned by finalize_nrv into
<retval>.fn ();

Then the newly added call to cp_get_callee_fndecl calls maybe_constant_init,
which ends up evaluating <retval>, but it's not in the hash map, so we crash
here:
4111       /* We ask for an rvalue for the RESULT_DECL when indirecting
4112          through an invisible reference, or in named return value
4113          optimization.  */
4114       return (*ctx->values->get (t));

I thought we could be more careful and not blindly dereference the result
of get().  After all, it's not a problem here if the <retval> cannot be
evaluated to a constant.

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

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

	PR c++/84978
	* constexpr.c (cxx_eval_constant_expression): Handle the case when
	a RESULT_DECL isn't in the hash map.

	* g++.dg/opt/nrv19.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 894bcd0bb3e..1f8ece89730 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -4111,7 +4111,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       /* We ask for an rvalue for the RESULT_DECL when indirecting
 	 through an invisible reference, or in named return value
 	 optimization.  */
-      return (*ctx->values->get (t));
+      if (tree *p = ctx->values->get (t))
+	return *p;
+      else
+	{
+	  if (!ctx->quiet)
+	    error ("%qE is not a constant expression", t);
+	  *non_constant_p = true;
+	}
+      break;
 
     case VAR_DECL:
       if (DECL_HAS_VALUE_EXPR_P (t))
diff --git gcc/testsuite/g++.dg/opt/nrv19.C gcc/testsuite/g++.dg/opt/nrv19.C
index e69de29bb2d..385593cc90c 100644
--- gcc/testsuite/g++.dg/opt/nrv19.C
+++ gcc/testsuite/g++.dg/opt/nrv19.C
@@ -0,0 +1,15 @@
+// PR c++/84978
+// { dg-do compile }
+
+struct S {
+  void (*fn)();
+  int a[10];
+};
+
+S
+foo ()
+{
+  S s;
+  s.fn ();
+  return s;
+}

	Marek


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