From: Marek Polacek Date: Fri, 7 Feb 2020 19:44:25 +0000 (-0500) Subject: c++: Fix paren init of aggregates in unevaluated context [PR92947] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ac6eaa55a5199196ea0a25763114ce05333a14d3;p=gcc.git c++: Fix paren init of aggregates in unevaluated context [PR92947] When I implemented C++20 parenthesized initialization of aggregates I introduced this bogus cp_unevaluated_operand check, thus disabling this feature in unevaluated context. Oop. Removing the check turned up another bug: I wasn't checking the return value of digest_init. So when constructible_expr called build_new_method_call_1 to see if we can construct one type from another, it got back a bogus INIT_EXPR that looked something like *(struct T &) 1 = <<< error >>>. But that isn't the error_mark_node, so constructible_expr thought we had been successful in creating the ctor call, and it gave the wrong answer. Covered by paren-init17.C. PR c++/92947 - Paren init of aggregates in unevaluated context. * call.c (build_new_method_call_1): Don't check cp_unevaluated_operand. Check the return value of digest_init. * g++.dg/cpp2a/paren-init21.C: New test. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 580b7665c67..f1fe7747f39 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-07 Marek Polacek + + PR c++/92947 - Paren init of aggregates in unevaluated context. + * call.c (build_new_method_call_1): Don't check + cp_unevaluated_operand. Check the return value of digest_init. + 2020-02-06 Jason Merrill PR c++/92654 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index fde29f8f631..51621b7dd87 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10179,7 +10179,6 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, the two. */ if (DECL_CONSTRUCTOR_P (fn) && !(flags & LOOKUP_ONLYCONVERTING) - && !cp_unevaluated_operand && cxx_dialect >= cxx2a && CP_AGGREGATE_TYPE_P (basetype) && !user_args->is_empty ()) @@ -10194,6 +10193,8 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, else { ctor = digest_init (basetype, ctor, complain); + if (ctor == error_mark_node) + return error_mark_node; ctor = build2 (INIT_EXPR, TREE_TYPE (instance), instance, ctor); TREE_SIDE_EFFECTS (ctor) = true; return ctor; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4a4550bf351..63836b9a44e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-07 Marek Polacek + + PR c++/92947 - Paren init of aggregates in unevaluated context. + * g++.dg/cpp2a/paren-init21.C: New test. + 2020-02-07 Will Schmidt * testsuite/gcc.target/powerpc/pr92923-1.c: Add -mvsx. diff --git a/gcc/testsuite/g++.dg/cpp2a/paren-init21.C b/gcc/testsuite/g++.dg/cpp2a/paren-init21.C new file mode 100644 index 00000000000..cfd37193f66 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/paren-init21.C @@ -0,0 +1,14 @@ +// PR c++/92947 - Paren init of aggregates in unevaluated context. +// { dg-do compile { target c++2a } } + +struct A { + int a; + int b; +}; + +int main() +{ + static_assert(__is_constructible(A, int, int)); + decltype(A(1,2)) foo; + bool b = noexcept(A(1,2)); +}