I'm backporting these 5 patches to gcc-8. Marek
2019-02-27 Marek Polacek <pola...@redhat.com>
PR c++/88857 - ICE with value-initialization of argument in template. * call.c (convert_like_real): Don't call build_value_init in template. --- gcc/cp/call.c +++ gcc/cp/call.c @@ -7005,7 +7005,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* If we're initializing from {}, it's value-initialization. */ if (BRACE_ENCLOSED_INITIALIZER_P (expr) && CONSTRUCTOR_NELTS (expr) == 0 - && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)) + && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype) + && !processing_template_decl) { bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr); if (abstract_virtuals_error_sfinae (NULL_TREE, totype, complain)) --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/initlist-value4.C @@ -0,0 +1,12 @@ +// PR c++/88857 +// { dg-do compile { target c++11 } } + +class S { int a; }; +void foo (const S &, int); + +template <int N> +void +bar () +{ + foo ({}); // { dg-error "too few arguments to function" } +}
2019-03-25 Marek Polacek <pola...@redhat.com> PR c++/89214 - ICE when initializing aggregates with bases. * typeck2.c (digest_init_r): Warn about object slicing instead of crashing. --- gcc/cp/typeck2.c +++ gcc/cp/typeck2.c @@ -1209,8 +1209,29 @@ digest_init_r (tree type, tree init, int nested, int flags, { tree elt = CONSTRUCTOR_ELT (stripped_init, 0)->value; if (reference_related_p (type, TREE_TYPE (elt))) - /* We should have fixed this in reshape_init. */ - gcc_unreachable (); + { + /* In C++17, aggregates can have bases, thus participate in + aggregate initialization. In the following case: + + struct B { int c; }; + struct D : B { }; + D d{{D{{42}}}}; + + there's an extra set of braces, so the D temporary initializes + the first element of d, which is the B base subobject. The base + of type B is copy-initialized from the D temporary, causing + object slicing. */ + tree field = next_initializable_field (TYPE_FIELDS (type)); + if (field && DECL_FIELD_IS_BASE (field)) + { + if (warning_at (loc, 0, "initializing a base class of type %qT " + "results in object slicing", TREE_TYPE (field))) + inform (loc, "remove %<{ }%> around initializer"); + } + else + /* We should have fixed this in reshape_init. */ + gcc_unreachable (); + } } if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init) --- /dev/null +++ gcc/testsuite/g++.dg/cpp1z/aggr-base8.C @@ -0,0 +1,48 @@ +// PR c++/89214 +// { dg-do compile { target c++17 } } + +struct A +{ + A (int); +}; + +struct BB +{ + A a; +}; + +struct B : BB +{ +}; + +void +foo () +{ + B b1 = {42}; + B b2 = {{42}}; + B b3 = {{{42}}}; + + B b4 = B{42}; + B b5 = B{{42}}; + B b6 = B{{{42}}}; + + B b7 = {B{42}}; + B b8 = {B{{42}}}; + B b9 = {B{{{42}}}}; + + B b10 = {{B{42}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" } + B b11 = {{B{{42}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" } + B b12 = {{B{{{42}}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" } + + B bb1{42}; + B bb2{{42}}; + B bb3{{{42}}}; + + B bb7{B{42}}; + B bb8{B{{42}}}; + B bb9{B{{{42}}}}; + + B bb10{{B{42}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" } + B bb11{{B{{42}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" } + B bb12{{B{{{42}}}}}; // { dg-warning "initializing a base class of type .BB. results in object slicing" } +} --- /dev/null +++ gcc/testsuite/g++.dg/cpp1z/aggr-base9.C @@ -0,0 +1,33 @@ +// PR c++/89214 +// { dg-do compile { target c++17 } } + +struct B { + int c; +}; + +struct D : B { }; + +void +foo () +{ + D d1 = {42}; + D d2 = {{42}}; + + D d4 = D{42}; + D d5 = D{{42}}; + + D d7 = {D{42}}; + D d8 = {D{{42}}}; + + D d10 = {{D{42}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" } + D d11 = {{D{{42}}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" } + + D dd1{42}; + D dd2{{42}}; + + D dd7{D{42}}; + D dd8{D{{42}}}; + + D dd10{{D{42}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" } + D dd11{{D{{42}}}}; // { dg-warning "initializing a base class of type .B. results in object slicing" } +}
2019-02-27 Marek Polacek <pola...@redhat.com> PR c++/89511 - ICE with using-declaration and unscoped enumerator. * parser.c (cp_parser_using_declaration): For an unscoped enum only use its context if it's not a function declaration. --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -19412,7 +19412,8 @@ cp_parser_using_declaration (cp_parser* parser, /*is_declaration=*/true); if (!qscope) qscope = global_namespace; - else if (UNSCOPED_ENUM_P (qscope)) + else if (UNSCOPED_ENUM_P (qscope) + && !TYPE_FUNCTION_SCOPE_P (qscope)) qscope = CP_TYPE_CONTEXT (qscope); if (access_declaration_p && cp_parser_error_occurred (parser)) --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/using-enum-3.C @@ -0,0 +1,21 @@ +// PR c++/89511 +// { dg-do compile { target c++11 } } + +void f () +{ + enum e { a }; + using e::a; // { dg-error "not a namespace or unscoped enum" } +} + +struct S { + enum E { A }; + using E::A; // { dg-error "type .S. is not a base type for type .S." } +}; + +namespace N { + enum E { B }; +} + +struct T { + using N::E::B; // { dg-error "using-declaration for non-member at class scope" } +};
2019-03-25 Marek Polacek <pola...@redhat.com> PR c++/89705 - ICE with reference binding with conversion function. * call.c (reference_binding): If the result of the conversion function is a prvalue of non-class type, use the cv-unqualified type. diff --git gcc/cp/call.c gcc/cp/call.c index f16f2895402..c5ef07d0bee 100644 --- gcc/cp/call.c +++ gcc/cp/call.c @@ -1767,6 +1767,9 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, && DECL_CONV_FN_P (t->cand->fn)) { tree ftype = TREE_TYPE (TREE_TYPE (t->cand->fn)); + /* A prvalue of non-class type is cv-unqualified. */ + if (TREE_CODE (ftype) != REFERENCE_TYPE && !CLASS_TYPE_P (ftype)) + ftype = cv_unqualified (ftype); int sflags = (flags|LOOKUP_NO_CONVERSION)&~LOOKUP_NO_TEMP_BIND; conversion *new_second = reference_binding (rto, ftype, NULL_TREE, c_cast_p, diff --git gcc/testsuite/g++.dg/cpp0x/rv-conv2.C gcc/testsuite/g++.dg/cpp0x/rv-conv2.C new file mode 100644 index 00000000000..9b9b154995b --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/rv-conv2.C @@ -0,0 +1,18 @@ +// PR c++/89705 +// { dg-do compile { target c++11 } } + +struct W { operator const volatile int(); }; +const int& rci = W(); + +struct X { operator const int(); }; +int&& rri = X(); + +struct Y { operator volatile int(); }; +int&& rri2 = Y(); + +struct Z { operator const volatile int(); }; +volatile int&& rri3 = Z(); + +enum E { A }; +struct S { operator const E(); }; +E&& rre = S();
2019-03-29 Marek Polacek <pola...@redhat.com> PR c++/89876 - ICE with deprecated conversion. * call.c (convert_like_real): Only give warnings with tf_warning. --- gcc/cp/call.c +++ gcc/cp/call.c @@ -7446,7 +7446,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, case ck_qual: /* Warn about deprecated conversion if appropriate. */ - string_conv_p (totype, expr, 1); + if (complain & tf_warning) + string_conv_p (totype, expr, 1); break; case ck_ptr: --- /dev/null +++ gcc/testsuite/g++.dg/warn/conv5.C @@ -0,0 +1,11 @@ +// PR c++/89876 +// { dg-do compile { target c++11 } } +// { dg-prune-output "sorry" } + +template <typename T> +T f (T, char*); + +template <typename T> +decltype (f (T (), "")) g (T) { return ""; } // { dg-error "invalid conversion" } + +void h () { g (0); }