Message ID | 20181116090029.GG11625@tucnak |
---|---|
State | New |
Headers | show |
Series | [C++] Don't incorrectly reject {un,}signed char constexpr array initialization in templates (PR c++/87476) | expand |
Hi! On Fri, Nov 16, 2018 at 10:00:29AM +0100, Jakub Jelinek wrote: > 2018-11-16 Jakub Jelinek <jakub@redhat.com> > > PR c++/87476 > * typeck2.c (digest_init_r): Re-add handing of signed/unsigned char > strings and add it to the initialization of wide array from non-wide > string diagnostics too. > > * g++.dg/cpp0x/pr87476-1.C: New test. > * g++.dg/cpp0x/pr87476-2.C: New test. I'd like to ping this patch. Jakub
On 11/16/18 4:00 AM, Jakub Jelinek wrote: > Hi! > > The following two testcases, one is a regression from GCC 8 (introduced by > the constructor to STRING_CST optimization), the other seems to fail since > C++11 support has been introduced (but is accepted by clang++) fail, > because during parsing with processing_template_decl we end up with creating > a STRING_CST with type of {un,}signed char array and later during > instantiation digest_init_r rejects it, because it already has such a type > rather than what it expects (char array) and bogusly complains that it is a > wide string. > > The following patch fixes that. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2018-11-16 Jakub Jelinek <jakub@redhat.com> > > PR c++/87476 > * typeck2.c (digest_init_r): Re-add handing of signed/unsigned char > strings and add it to the initialization of wide array from non-wide > string diagnostics too. OK. Jason
--- gcc/cp/typeck2.c.jj 2018-09-25 15:14:43.961258143 +0200 +++ gcc/cp/typeck2.c 2018-11-15 22:04:46.723230224 +0100 @@ -1063,7 +1063,9 @@ digest_init_r (tree type, tree init, int if (TYPE_PRECISION (typ1) == BITS_PER_UNIT) { - if (char_type != char_type_node) + if (char_type != char_type_node + && char_type != signed_char_type_node + && char_type != unsigned_char_type_node) { if (complain & tf_error) error_at (loc, "char-array initialized from wide string"); @@ -1072,7 +1074,9 @@ digest_init_r (tree type, tree init, int } else { - if (char_type == char_type_node) + if (char_type == char_type_node + || char_type == signed_char_type_node + || char_type == unsigned_char_type_node) { if (complain & tf_error) error_at (loc, --- gcc/testsuite/g++.dg/cpp0x/pr87476-1.C.jj 2018-11-15 17:52:13.736758511 +0100 +++ gcc/testsuite/g++.dg/cpp0x/pr87476-1.C 2018-11-15 17:42:03.577770280 +0100 @@ -0,0 +1,13 @@ +// PR c++/87476 +// { dg-do compile { target c++11 } } + +template <int> +struct S { + void operator () () { constexpr unsigned char p[1] {}; } +}; + +void +foo () +{ + S<0>{} (); +} --- gcc/testsuite/g++.dg/cpp0x/pr87476-2.C.jj 2018-11-15 22:06:27.615571180 +0100 +++ gcc/testsuite/g++.dg/cpp0x/pr87476-2.C 2018-11-15 22:06:36.768420670 +0100 @@ -0,0 +1,23 @@ +// PR c++/87476 +// { dg-do compile { target c++11 } } + +void f0 () { constexpr char p[] = "11111"; } +void f1 () { constexpr unsigned char p[] = "11111"; } +void f2 () { constexpr signed char p[] = "11111"; } +template <int N> +void f3 () { constexpr char p[] = "11111"; } +template <int N> +void f4 () { constexpr unsigned char p[] = "11111"; } +template <int N> +void f5 () { constexpr signed char p[] = "11111"; } + +void +baz () +{ + f0 (); + f1 (); + f2 (); + f3<0> (); + f4<0> (); + f5<0> (); +}