From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 87450 invoked by alias); 23 Sep 2016 17:35:30 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 87432 invoked by uid 89); 23 Sep 2016 17:35:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM autolearn=no version=3.3.2 spammy=H*F:U*jason X-HELO: mail-oi0-f42.google.com Received: from mail-oi0-f42.google.com (HELO mail-oi0-f42.google.com) (209.85.218.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 23 Sep 2016 17:35:25 +0000 Received: by mail-oi0-f42.google.com with SMTP id w11so142446521oia.2 for ; Fri, 23 Sep 2016 10:35:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=f/FiT4O4ngO8wy3EaD9Zj1m1mYo1p5BlwpTm7j0sTiM=; b=KuckgFJb9vK00VNB22hAEJiMFLIPTnj6YrOCkanRwgNJOwHi2WFqNCkxuuc86MAzoJ nbuV/mJhFdXqD3CqZFy2NzrpIK7BFTI9vOIjwC8h8e65+X/iXhVlyWp4PFkLvnUVQWO7 MHvPWr+GjLZ6MoRp5iq7SgVOs6e29kWEiotT4ffw2wNOQ2IUdfTEJ+/o9I/z1QBwhjWg CCuNZ++gUdyyJ3rcF2IwMVqgsIPmb8MeV/yc1X+3TV9G0NTURhmB+o4IQz8NtQpoucXe n0ERNkU2YLvJ5GQZHsAxqGgzmxBMWjw9GIbxiMfs+GDkS1TP3JOHtEFyj2lHrghOiOK3 SXJA== X-Gm-Message-State: AE9vXwNv7Tq2IPzEGJ0STOGAc0JO85DLnmS6fCheb337j0OaM85wbt0P+zIuhVgsQ4H91gmCaOKu9J8Lr4Bm17qX X-Received: by 10.202.236.66 with SMTP id k63mr11420176oih.127.1474652123944; Fri, 23 Sep 2016 10:35:23 -0700 (PDT) MIME-Version: 1.0 Received: by 10.182.105.167 with HTTP; Fri, 23 Sep 2016 10:35:03 -0700 (PDT) In-Reply-To: <20160923171433.GU7282@tucnak.redhat.com> References: <20160923171433.GU7282@tucnak.redhat.com> From: Jason Merrill Date: Fri, 23 Sep 2016 17:42:00 -0000 Message-ID: Subject: Re: [C++ PATCH] Implement P0138R2, C++17 construction rules for enum class values To: Jakub Jelinek Cc: gcc-patches List Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2016-09/txt/msg01726.txt.bz2 OK. On Fri, Sep 23, 2016 at 1:14 PM, Jakub Jelinek wrote: > Hi! > > The following patch implements direct enum initialization as per C++17. > The change in reshape_init is needed for when it is called from > check_initializer and finish_compound_literal for e.g. E e { 5 } and > E { 5 } respectively, while the convert_for_assignment spot handles all the > other cases, which don't go through reshape_init, but on the other side > reshape_init strips away the CONSTRUCTOR needed to determine when to do this > and when not. > > Bootstrapped/regtested on x86_64-linux and i686-linux, additionally > regtested on both with make -C gcc check-c++-all. Ok for trunk? > > 2016-09-23 Jakub Jelinek > > Implement P0138R2, C++17 construction rules for enum class values > * cp-tree.h (is_direct_enum_init): Declare. > * decl.c (is_direct_enum_init): New function. > (reshape_init): Use it. > * typeck.c (convert_for_assignment): Likewise. > > * g++.dg/cpp1z/direct-enum-init1.C: New test. > > --- gcc/cp/cp-tree.h.jj 2016-09-23 09:32:09.440454087 +0200 > +++ gcc/cp/cp-tree.h 2016-09-23 12:28:47.559905330 +0200 > @@ -5829,6 +5829,7 @@ extern tree check_elaborated_type_specif > extern void warn_extern_redeclared_static (tree, tree); > extern tree cxx_comdat_group (tree); > extern bool cp_missing_noreturn_ok_p (tree); > +extern bool is_direct_enum_init (tree, tree); > extern void initialize_artificial_var (tree, vec *); > extern tree check_var_type (tree, tree); > extern tree reshape_init (tree, tree, tsubst_flags_t); > --- gcc/cp/decl.c.jj 2016-09-23 09:33:36.770328046 +0200 > +++ gcc/cp/decl.c 2016-09-23 12:28:47.563905279 +0200 > @@ -5581,6 +5581,22 @@ next_initializable_field (tree field) > return field; > } > > +/* Return true for [dcl.init.list] direct-list-initialization from > + single element of enumeration with a fixed underlying type. */ > + > +bool > +is_direct_enum_init (tree type, tree init) > +{ > + if (cxx_dialect >= cxx1z > + && TREE_CODE (type) == ENUMERAL_TYPE > + && ENUM_FIXED_UNDERLYING_TYPE_P (type) > + && TREE_CODE (init) == CONSTRUCTOR > + && CONSTRUCTOR_IS_DIRECT_INIT (init) > + && CONSTRUCTOR_NELTS (init) == 1) > + return true; > + return false; > +} > + > /* Subroutine of reshape_init_array and reshape_init_vector, which does > the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an > INTEGER_CST representing the size of the array minus one (the maximum index), > @@ -6026,6 +6042,17 @@ reshape_init (tree type, tree init, tsub > if (vec_safe_is_empty (v)) > return init; > > + /* Handle [dcl.init.list] direct-list-initialization from > + single element of enumeration with a fixed underlying type. */ > + if (is_direct_enum_init (type, init)) > + { > + tree elt = CONSTRUCTOR_ELT (init, 0)->value; > + if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain)) > + return cp_build_c_cast (type, elt, tf_warning_or_error); > + else > + return error_mark_node; > + } > + > /* Recurse on this CONSTRUCTOR. */ > d.cur = &(*v)[0]; > d.end = d.cur + v->length (); > --- gcc/cp/typeck.c.jj 2016-09-14 23:49:03.000000000 +0200 > +++ gcc/cp/typeck.c 2016-09-23 13:35:23.369149388 +0200 > @@ -8266,6 +8266,17 @@ convert_for_assignment (tree type, tree > if (TREE_CODE (rhs) == NON_LVALUE_EXPR) > rhs = TREE_OPERAND (rhs, 0); > > + /* Handle [dcl.init.list] direct-list-initialization from > + single element of enumeration with a fixed underlying type. */ > + if (is_direct_enum_init (type, rhs)) > + { > + tree elt = CONSTRUCTOR_ELT (rhs, 0)->value; > + if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain)) > + rhs = cp_build_c_cast (type, elt, complain); > + else > + rhs = error_mark_node; > + } > + > rhstype = TREE_TYPE (rhs); > coder = TREE_CODE (rhstype); > > --- gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C.jj 2016-09-23 12:28:47.565905254 +0200 > +++ gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C 2016-09-23 16:37:49.596043501 +0200 > @@ -0,0 +1,237 @@ > +// P0138R2 - direct-list-initialization of enums > +// { dg-do compile { target c++11 } } > + > +enum A { G = 26 }; > +enum B : short {}; > +enum class C {}; > +enum struct D : long {}; > +enum class E : unsigned char { e = 7 }; > +struct S { operator C () { return C (s); } int s; } s; > +struct T { operator long () { return t; } long t; } t; > +struct V { E v; }; > +long l; > +long long ll; > +short c; > +void bar (E); > + > +void > +foo () > +{ > + A a1 { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" } > + B b1 { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + C c1 { s }; > + D d1 { D(t) }; // { dg-error "invalid cast from type 'T' to type 'D'" } > + D d2 { t }; // { dg-error "cannot convert 'T' to 'D' in initialization" "" { target c++14_down } } > + // { dg-error "invalid cast from type 'T' to type 'D'" "" { target c++1z } .-1 } > + D d3 { 9 }; // { dg-error "cannot convert 'int' to 'D' in initialization" "" { target c++14_down } } > + D d4 { l }; // { dg-error "cannot convert 'long int' to 'D' in initialization" "" { target c++14_down } } > + D d5 { D(l) }; > + D d6 { G }; // { dg-error "cannot convert 'A' to 'D' in initialization" "" { target c++14_down } } > + E e1 { 5 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + E e2 { -1 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '-1' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 } > + E e3 { 5.0 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + E e4 { 5.2 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.\[0-9]*e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + B b2 = { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" } > + C c2 = { C { 8 } }; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } } > + > + D *d7 = new D { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } } > + E *e5 = new E { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 } > + bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" } > + bar (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + V v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" } > + V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + V v3 = { E { 5.0 } }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + V v4 = { 13 }; // { dg-error "cannot convert 'int' to 'E' in initialization" } > + if (B b3 { 5 }) // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + ; > + if (B b4 { 4.0 }) // { dg-error "cannot convert 'double' to 'B' in initialization" "" { target c++14_down } } > + ; // { dg-error "narrowing conversion of '4.0e.0' from 'double' to 'short int' inside" "" { target c++1z } .-1 } > + C c3 { 8L }; // { dg-error "cannot convert 'long int' to 'C' in initialization" "" { target c++14_down } } > + B b4 {short (c + 5)}; // { dg-error "invalid conversion from 'short int' to 'B'" "" { target c++14_down } } > + B b5 {c + 5}; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + // { dg-error "narrowing conversion of \[^\n\r]* from 'int' to 'short int' inside" "" { target c++1z } .-1 } > + C c4 { ll }; // { dg-error "cannot convert 'long long int' to 'C' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of 'll' from 'long long int' to 'int' inside" "" { target c++1z } .-1 } > + C c5 {short (c + 5)}; // { dg-error "cannot convert 'short int' to 'C' in initialization" "" { target c++14_down } } > + C c6 {c + 5}; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } } > +} > + > +struct U > +{ > + U () : e { 5 } {} // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + U (int) : e { 5.0 } {}// { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + U (float) : e({ 6 }) {}// { dg-error "list-initializer for non-class type must not be parenthesized" } > + // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target *-*-* } .-1 } > + E e; > +}; > + > +struct W > +{ > + A a { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" } > + B b { 6 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + C c { 3.0f }; // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-1 } > + D d = { 7 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" } > +}; > + > +template > +void > +foo2 () > +{ > + A a1 { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" } > + B b1 { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + C c1 { s }; > + D d1 { D(t) }; // { dg-error "invalid cast from type 'T' to type 'D'" } > + D d2 { t }; // { dg-error "cannot convert 'T' to 'D' in initialization" "" { target c++14_down } } > + // { dg-error "invalid cast from type 'T' to type 'D'" "" { target c++1z } .-1 } > + D d3 { 9 }; // { dg-error "cannot convert 'int' to 'D' in initialization" "" { target c++14_down } } > + D d4 { l }; // { dg-error "cannot convert 'long int' to 'D' in initialization" "" { target c++14_down } } > + D d5 { D(l) }; > + D d6 { G }; // { dg-error "cannot convert 'A' to 'D' in initialization" "" { target c++14_down } } > + E e1 { 5 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + E e2 { -1 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '-1' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 } > + E e3 { 5.0 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + E e4 { 5.2 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.\[0-9]*e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + B b2 = { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" } > + C c2 = { C { 8 } }; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } } > + D *d7 = new D { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } } > + E *e5 = new E { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 } > + bar ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" } > + bar (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + V v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" } > + V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + V v3 = { E { 5.0 } }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + V v4 = { 13 }; // { dg-error "cannot convert 'int' to 'E' in initialization" } > + if (B b3 { 5 }) // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + ; > + if (B b4 { 4.0 }) // { dg-error "cannot convert 'double' to 'B' in initialization" "" { target c++14_down } } > + ; // { dg-error "narrowing conversion of '4.0e.0' from 'double' to 'short int' inside" "" { target c++1z } .-1 } > + C c3 { 8L }; // { dg-error "cannot convert 'long int' to 'C' in initialization" "" { target c++14_down } } > + B b4 {short (c + 5)}; // { dg-error "invalid conversion from 'short int' to 'B'" "" { target c++14_down } } > + B b5 {c + 5}; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + // { dg-error "narrowing conversion of \[^\n\r]* from 'int' to 'short int' inside" "" { target c++1z } .-1 } > + C c4 { ll }; // { dg-error "cannot convert 'long long int' to 'C' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of 'll' from 'long long int' to 'int' inside" "" { target c++1z } .-1 } > + C c5 {short (c + 5)}; // { dg-error "cannot convert 'short int' to 'C' in initialization" "" { target c++14_down } } > + C c6 {c + 5}; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } } > +} > + > +template > +struct U2 > +{ > + U2 () : e { 5 } {} // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + U2 (int) : e { 5.0 } {}// { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + U2 (float) : e({ 6 }) {} > + E e; > +}; > + > +template > +struct W2 > +{ > + A a { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" "" { target *-*-* } .-2 } > + B b { 6 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-3 } > + C c { 3.0f }; // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-4 } > + // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-5 } > + D d = { 7 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-6 } > +}; > + > +template > +void > +foo3 () > +{ > + void bar3 (L); > + H a1 { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" } > + I b1 { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + J c1 { s }; > + K d1 { K(t) }; // { dg-error "invalid cast from type 'T' to type 'D'" } > + K d2 { t }; // { dg-error "cannot convert 'T' to 'D' in initialization" "" { target c++14_down } } > + // { dg-error "invalid cast from type 'T' to type 'D'" "" { target c++1z } .-1 } > + K d3 { 9 }; // { dg-error "cannot convert 'int' to 'D' in initialization" "" { target c++14_down } } > + K d4 { l }; // { dg-error "cannot convert 'long int' to 'D' in initialization" "" { target c++14_down } } > + K d5 { K(l) }; > + K d6 { G }; // { dg-error "cannot convert 'A' to 'D' in initialization" "" { target c++14_down } } > + L e1 { 5 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + L e2 { -1 }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '-1' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 } > + L e3 { 5.0 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + L e4 { 5.2 }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.\[0-9]*e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + I b2 = { 7 }; // { dg-error "invalid conversion from 'int' to 'B'" } > + J c2 = { J { 8 } }; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } } > + K *d7 = new K { 9 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target c++14_down } } > + L *e5 = new L { -4 }; // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char' inside" "" { target c++1z } .-1 } > + bar3 ({ 10 }); // { dg-error "cannot convert \[^\n\r]* to 'E' for argument" } > + bar3 (E { 9 }); // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + M v1 = { { 11 } }; // { dg-error "braces around scalar initializer for type 'E'" } > + M v2 = { L { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } } > + M v3 = { L { 5.0 } }; // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + M v4 = { 13 }; // { dg-error "cannot convert 'int' to 'E' in initialization" } > + if (I b3 { 5 }) // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + ; > + if (I b4 { 4.0 }) // { dg-error "cannot convert 'double' to 'B' in initialization" "" { target c++14_down } } > + ; // { dg-error "narrowing conversion of '4.0e.0' from 'double' to 'short int' inside" "" { target c++1z } .-1 } > + J c3 { 8L }; // { dg-error "cannot convert 'long int' to 'C' in initialization" "" { target c++14_down } } > + I b4 {short (c + 5)}; // { dg-error "invalid conversion from 'short int' to 'B'" "" { target c++14_down } } > + I b5 {c + 5}; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } } > + // { dg-error "narrowing conversion of \[^\n\r]* from 'int' to 'short int' inside" "" { target c++1z } .-1 } > + J c4 { ll }; // { dg-error "cannot convert 'long long int' to 'C' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of 'll' from 'long long int' to 'int' inside" "" { target c++1z } .-1 } > + J c5 {short (c + 5)}; // { dg-error "cannot convert 'short int' to 'C' in initialization" "" { target c++14_down } } > + J c6 {c + 5}; // { dg-error "cannot convert 'int' to 'C' in initialization" "" { target c++14_down } } > +} > + > +template > +struct U3 > +{ > + U3 () : e { 5 } {} // { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + U3 (int) : e { 5.0 } {}// { dg-error "cannot convert \[^\n\r]* to 'E' in initialization" "" { target c++14_down } } > + // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char' inside" "" { target c++1z } .-1 } > + U3 (float) : e({ 6 }) {} > + L e; > +}; > + > +template > +struct W3 > +{ > + H a { 5 }; // { dg-error "invalid conversion from 'int' to 'A'" "" { target *-*-* } .-2 } > + I b { 6 }; // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-3 } > + J c { 3.0f }; // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-4 } > + // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-5 } > + K d = { 7 }; // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-6 } > +}; > + > +void > +test () > +{ > + foo2<0> (); > + U2<0> u20; > + U2<1> u21 (5); > + W2<0> w2; // { dg-error "invalid conversion from 'int' to 'A'" } > + // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-1 } > + // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-2 } > + // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-3 } > + // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-4 } > + foo3 (); > + U3 u30; > + U3 u31 (5); > + W3 w3; // { dg-error "invalid conversion from 'int' to 'A'" } > + // { dg-error "invalid conversion from 'int' to 'B'" "" { target c++14_down } .-1 } > + // { dg-error "cannot convert \[^\n\r]* to 'C' in initialization" "" { target c++14_down } .-2 } > + // { dg-error "narrowing conversion of '3.0e.0f' from 'float' to 'int' inside" "" { target c++1z } .-3 } > + // { dg-error "cannot convert \[^\n\r]* to 'D' in initialization" "" { target *-*-* } .-4 } > +} > > Jakub