Re: [C++ PATCH] Fix error-recovery with constexpr dtor (PR c++/92414)

2019-11-19 Thread Jason Merrill

On 11/18/19 11:22 PM, Jakub Jelinek wrote:

On Mon, Nov 18, 2019 at 02:38:51PM -0500, Jason Merrill wrote:

On 11/8/19 9:14 AM, Jakub Jelinek wrote:

Hi!

We ICE on the following testcase, because DECL_INITIAL (decl) is
error_mark_node due to previously reported error and
cxx_eval_outermost_constant_expr is unhappy if ctx.ctor is not
a CONSTRUCTOR, but error_mark_node.

If the initializer is invalid, it should have been diagnosed already and
there is no need to try to evaluate constexpr dtor on it.

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

2019-11-08  Jakub Jelinek  

PR c++/92414
* constexpr.c (cxx_constant_dtor): Don't call
cxx_eval_outermost_constant_expr if DECL_INITIAL is erroneous.


Why add the error-checking here rather than in
cxx_eval_outermost_constant_expr when we use DECL_INITIAL?


So like this?
Also passed bootstrap/regtest on x86_64-linux and i686-linux:


OK, thanks.


2019-11-19  Jakub Jelinek  

PR c++/92414
* constexpr.c (cxx_eval_outermost_constant_expr): If DECL_INITIAL
on object is erroneous, return t without trying to evaluate
a constexpr dtor.

* g++.dg/cpp2a/constexpr-dtor4.C: New test.

--- gcc/cp/constexpr.c.jj   2019-11-18 21:50:49.539233013 +0100
+++ gcc/cp/constexpr.c  2019-11-18 21:52:47.217475549 +0100
@@ -5834,6 +5834,8 @@ cxx_eval_outermost_constant_expr (tree t
  gcc_assert (object && VAR_P (object));
  gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
  gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
+ if (error_operand_p (DECL_INITIAL (object)))
+   return t;
  ctx.ctor = unshare_expr (DECL_INITIAL (object));
  TREE_READONLY (ctx.ctor) = false;
  /* Temporarily force decl_really_constant_value to return false
--- gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C.jj 2019-11-18 
21:50:56.152134256 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C2019-11-18 
21:50:56.152134256 +0100
@@ -0,0 +1,15 @@
+// PR c++/92414
+// { dg-do compile { target c++2a } }
+
+struct A { virtual void foo (); };
+
+struct B : A {
+  constexpr B (int);   // { dg-warning "used but never defined" }
+  constexpr ~B () { }
+};
+
+struct D : B {
+  constexpr D () : B (42) { }  // { dg-error "used before its definition" }
+};
+
+constexpr D d; // { dg-message "in 'constexpr' expansion of" }


Jakub





Re: [C++ PATCH] Fix error-recovery with constexpr dtor (PR c++/92414)

2019-11-18 Thread Jakub Jelinek
On Mon, Nov 18, 2019 at 02:38:51PM -0500, Jason Merrill wrote:
> On 11/8/19 9:14 AM, Jakub Jelinek wrote:
> > Hi!
> > 
> > We ICE on the following testcase, because DECL_INITIAL (decl) is
> > error_mark_node due to previously reported error and
> > cxx_eval_outermost_constant_expr is unhappy if ctx.ctor is not
> > a CONSTRUCTOR, but error_mark_node.
> > 
> > If the initializer is invalid, it should have been diagnosed already and
> > there is no need to try to evaluate constexpr dtor on it.
> > 
> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> > 
> > 2019-11-08  Jakub Jelinek  
> > 
> > PR c++/92414
> > * constexpr.c (cxx_constant_dtor): Don't call
> > cxx_eval_outermost_constant_expr if DECL_INITIAL is erroneous.
> 
> Why add the error-checking here rather than in
> cxx_eval_outermost_constant_expr when we use DECL_INITIAL?

So like this?
Also passed bootstrap/regtest on x86_64-linux and i686-linux:

2019-11-19  Jakub Jelinek  

PR c++/92414
* constexpr.c (cxx_eval_outermost_constant_expr): If DECL_INITIAL
on object is erroneous, return t without trying to evaluate
a constexpr dtor.

* g++.dg/cpp2a/constexpr-dtor4.C: New test.

--- gcc/cp/constexpr.c.jj   2019-11-18 21:50:49.539233013 +0100
+++ gcc/cp/constexpr.c  2019-11-18 21:52:47.217475549 +0100
@@ -5834,6 +5834,8 @@ cxx_eval_outermost_constant_expr (tree t
  gcc_assert (object && VAR_P (object));
  gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
  gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
+ if (error_operand_p (DECL_INITIAL (object)))
+   return t;
  ctx.ctor = unshare_expr (DECL_INITIAL (object));
  TREE_READONLY (ctx.ctor) = false;
  /* Temporarily force decl_really_constant_value to return false
--- gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C.jj 2019-11-18 
21:50:56.152134256 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C2019-11-18 
21:50:56.152134256 +0100
@@ -0,0 +1,15 @@
+// PR c++/92414
+// { dg-do compile { target c++2a } }
+
+struct A { virtual void foo (); };
+
+struct B : A {
+  constexpr B (int);   // { dg-warning "used but never defined" }
+  constexpr ~B () { }
+};
+
+struct D : B {
+  constexpr D () : B (42) { }  // { dg-error "used before its definition" }
+};
+
+constexpr D d; // { dg-message "in 'constexpr' expansion of" }


Jakub



Re: [C++ PATCH] Fix error-recovery with constexpr dtor (PR c++/92414)

2019-11-18 Thread Jason Merrill

On 11/8/19 9:14 AM, Jakub Jelinek wrote:

Hi!

We ICE on the following testcase, because DECL_INITIAL (decl) is
error_mark_node due to previously reported error and
cxx_eval_outermost_constant_expr is unhappy if ctx.ctor is not
a CONSTRUCTOR, but error_mark_node.

If the initializer is invalid, it should have been diagnosed already and
there is no need to try to evaluate constexpr dtor on it.

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

2019-11-08  Jakub Jelinek  

PR c++/92414
* constexpr.c (cxx_constant_dtor): Don't call
cxx_eval_outermost_constant_expr if DECL_INITIAL is erroneous.


Why add the error-checking here rather than in 
cxx_eval_outermost_constant_expr when we use DECL_INITIAL?



* g++.dg/cpp2a/constexpr-dtor4.C: New test.

--- gcc/cp/constexpr.c.jj   2019-11-06 08:58:37.0 +0100
+++ gcc/cp/constexpr.c  2019-11-07 22:13:58.395840756 +0100
@@ -6024,7 +6024,8 @@ cxx_constant_value (tree t, tree decl)
  void
  cxx_constant_dtor (tree t, tree decl)
  {
-  cxx_eval_outermost_constant_expr (t, false, true, true, true, decl);
+  if (!error_operand_p (DECL_INITIAL (decl)))
+cxx_eval_outermost_constant_expr (t, false, true, true, true, decl);
  }
  
  /* Helper routine for fold_simple function.  Either return simplified

--- gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C.jj 2019-11-07 
22:16:56.943181785 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C2019-11-07 
22:18:16.752993443 +0100
@@ -0,0 +1,15 @@
+// PR c++/92414
+// { dg-do compile { target c++2a } }
+
+struct A { virtual void foo (); };
+
+struct B : A {
+  constexpr B (int);   // { dg-warning "used but never defined" }
+  constexpr ~B () { }
+};
+
+struct D : B {
+  constexpr D () : B (42) { }  // { dg-error "used before its definition" }
+};
+
+constexpr D d; // { dg-message "in 'constexpr' expansion of" }

Jakub





[C++ PATCH] Fix error-recovery with constexpr dtor (PR c++/92414)

2019-11-08 Thread Jakub Jelinek
Hi!

We ICE on the following testcase, because DECL_INITIAL (decl) is
error_mark_node due to previously reported error and
cxx_eval_outermost_constant_expr is unhappy if ctx.ctor is not
a CONSTRUCTOR, but error_mark_node.

If the initializer is invalid, it should have been diagnosed already and
there is no need to try to evaluate constexpr dtor on it.

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

2019-11-08  Jakub Jelinek  

PR c++/92414
* constexpr.c (cxx_constant_dtor): Don't call
cxx_eval_outermost_constant_expr if DECL_INITIAL is erroneous.

* g++.dg/cpp2a/constexpr-dtor4.C: New test.

--- gcc/cp/constexpr.c.jj   2019-11-06 08:58:37.0 +0100
+++ gcc/cp/constexpr.c  2019-11-07 22:13:58.395840756 +0100
@@ -6024,7 +6024,8 @@ cxx_constant_value (tree t, tree decl)
 void
 cxx_constant_dtor (tree t, tree decl)
 {
-  cxx_eval_outermost_constant_expr (t, false, true, true, true, decl);
+  if (!error_operand_p (DECL_INITIAL (decl)))
+cxx_eval_outermost_constant_expr (t, false, true, true, true, decl);
 }
 
 /* Helper routine for fold_simple function.  Either return simplified
--- gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C.jj 2019-11-07 
22:16:56.943181785 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-dtor4.C2019-11-07 
22:18:16.752993443 +0100
@@ -0,0 +1,15 @@
+// PR c++/92414
+// { dg-do compile { target c++2a } }
+
+struct A { virtual void foo (); };
+
+struct B : A {
+  constexpr B (int);   // { dg-warning "used but never defined" }
+  constexpr ~B () { }
+};
+
+struct D : B {
+  constexpr D () : B (42) { }  // { dg-error "used before its definition" }
+};
+
+constexpr D d; // { dg-message "in 'constexpr' expansion of" }

Jakub