Hi! The following testcase is rejected in 8.3, but was accepted in 8.2 and is in 9.x. This started with my PR87934 * constexpr.c (cxx_eval_constant_expression) <case CONSTRUCTOR>: Do re-process TREE_CONSTANT CONSTRUCTORs if they aren't reduced constant expressions. backport, where the NSDMI CONSTRUCTOR that contains CONST_DECLs is now constexpr evaluated so that it doesn't contain them. The difference from 9.x is that 9.x doesn't call get_target_expr if we got a CONSTRUCTOR for a class type for something that has been originally a CONSTRUCTOR too.
This patch cherry-picks just that hunk of the r9-3835 change. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for 8.4? Is the testcase alone ok for trunk/9.3? 2020-02-25 Jakub Jelinek <ja...@redhat.com> PR c++/93905 Backported from mainline 2018-11-04 Jason Merrill <ja...@redhat.com> * constexpr.c (cxx_eval_outermost_constant_expr): Don't wrap a CONSTRUCTOR if one was passed in. * g++.dg/cpp0x/pr93905.C: New test. --- gcc/cp/constexpr.c.jj 2020-02-25 14:04:47.912615737 +0100 +++ gcc/cp/constexpr.c 2020-02-25 21:05:02.537781661 +0100 @@ -4977,15 +4977,13 @@ cxx_eval_outermost_constant_expr (tree t if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_INITIAL (t) == r) return t; - else + else if (TREE_CODE (t) != CONSTRUCTOR) { r = get_target_expr (r); TREE_CONSTANT (r) = true; - return r; } } - else - return r; + return r; } /* Returns true if T is a valid subexpression of a constant expression, --- gcc/testsuite/g++.dg/cpp0x/pr93905.C.jj 2020-02-25 21:03:51.976820018 +0100 +++ gcc/testsuite/g++.dg/cpp0x/pr93905.C 2020-02-25 21:03:28.281168717 +0100 @@ -0,0 +1,18 @@ +// PR c++/93905 +// { dg-do compile { target c++11 } } + +enum class E { VALUE }; + +struct B { + E e{E::VALUE}; +protected: + ~B () = default; +}; + +struct D : B {}; + +int +main () +{ + D d{}; +} Jakub