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 <ja...@redhat.com>
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 <ja...@redhat.com>
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.C 2019-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