* [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms @ 2019-03-14 20:20 Alexandre Oliva 2019-03-14 20:22 ` Marek Polacek 0 siblings, 1 reply; 18+ messages in thread From: Alexandre Oliva @ 2019-03-14 20:20 UTC (permalink / raw) To: gcc-patches; +Cc: jason, nathan, ccoutant P0732R2 / C++ 2a introduce class literals as template parameters. The front-end uses VAR_DECLs constructed from such literals to bind the template PARM_DECLs, but dwarf2out.c used to reject such VAR_DECLs. Taking DECL_INITIAL from such VAR_DECLs enables the generation of DW_AT_const_value for them, at least when the class literal can actually be represented as such. Regstrapped on x86_64- and i686-linux-gnu. Ok to install? for gcc/ChangeLog PR c++/88534 PR c++/88537 * dwarf2out.c (generic_parameter_die): Follow DECL_INITIAL of VAR_DECL args. for gcc/ChangeLog PR c++/88534 PR c++/88537 * g++.dg/cpp2a/pr88534.C: New. * g++.dg/cpp2a/pr88537.C: New. --- gcc/dwarf2out.c | 7 ++++ gcc/testsuite/g++.dg/cpp2a/pr88534.C | 65 ++++++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/pr88537.C | 16 ++++++++ 3 files changed, 88 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88534.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88537.C diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 8305555681447..478d9b9b289b1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -13601,6 +13601,13 @@ generic_parameter_die (tree parm, tree arg, dw_die_ref tmpl_die = NULL; const char *name = NULL; + /* C++2a accepts class literals as template parameters, and var + decls with initializers represent them. The VAR_DECLs would be + rejected, but we can take the DECL_INITIAL constructor and + attempt to expand it. */ + if (TREE_CODE (arg) == VAR_DECL) + arg = DECL_INITIAL (arg); + if (!parm || !DECL_NAME (parm) || !arg) return NULL; diff --git a/gcc/testsuite/g++.dg/cpp2a/pr88534.C b/gcc/testsuite/g++.dg/cpp2a/pr88534.C new file mode 100644 index 0000000000000..54faf385f11aa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr88534.C @@ -0,0 +1,65 @@ +// { dg-do compile { target c++2a } } +// { dg-options "-g" } + +typedef __SIZE_TYPE__ size_t; + +namespace std +{ + +template <typename T, T... I> +struct integer_sequence +{ + typedef T value_type; + static constexpr size_t size () noexcept { return sizeof...(I); } +}; + +template <typename T, T N> +using make_integer_sequence = integer_sequence<T, __integer_pack (N)...>; + +template <size_t... I> +using index_sequence = integer_sequence<size_t, I...>; + +template <size_t N> +using make_index_sequence = make_integer_sequence<size_t, N>; +} + +template <typename T, size_t N> struct S +{ + T content[N]; + using char_type = T; + template <size_t... I> + constexpr S (const T (&input)[N], std::index_sequence<I...>) noexcept : content{input[I]...} { } + constexpr S (const T (&input)[N]) noexcept : S (input, std::make_index_sequence<N> ()) { } + constexpr size_t size () const noexcept + { + if (content[N - 1] == '\0') + return N - 1; + else + return N; + } + constexpr T operator[] (size_t i) const noexcept + { + return content[i]; + } + constexpr const T *begin () const noexcept + { + return content; + } + constexpr const T *end () const noexcept + { + return content + size (); + } +}; + +template <typename T, size_t N> S (const T (&)[N]) -> S<T, N>; + +template <S S> +struct F +{ +}; + +auto +foo () +{ + F<"test"> f; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/pr88537.C b/gcc/testsuite/g++.dg/cpp2a/pr88537.C new file mode 100644 index 0000000000000..d558d45f57830 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr88537.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++2a } } +// { dg-options "-g" } + +struct pair { + unsigned a; + unsigned b; + constexpr pair(unsigned _a, unsigned _b) noexcept: a{_a}, b{_b} { } +}; + +template <pair p> void fnc() { + +} + +void f() { + fnc<pair(10,20)>(); +} -- Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jamás-GNUChe ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-14 20:20 [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms Alexandre Oliva @ 2019-03-14 20:22 ` Marek Polacek 2019-03-14 20:33 ` Jason Merrill 0 siblings, 1 reply; 18+ messages in thread From: Marek Polacek @ 2019-03-14 20:22 UTC (permalink / raw) To: Alexandre Oliva; +Cc: gcc-patches, jason, nathan, ccoutant On Thu, Mar 14, 2019 at 05:14:49PM -0300, Alexandre Oliva wrote: > P0732R2 / C++ 2a introduce class literals as template parameters. The > front-end uses VAR_DECLs constructed from such literals to bind the > template PARM_DECLs, but dwarf2out.c used to reject such VAR_DECLs. > > Taking DECL_INITIAL from such VAR_DECLs enables the generation of > DW_AT_const_value for them, at least when the class literal can > actually be represented as such. > > Regstrapped on x86_64- and i686-linux-gnu. Ok to install? > > > for gcc/ChangeLog > > PR c++/88534 > PR c++/88537 > * dwarf2out.c (generic_parameter_die): Follow DECL_INITIAL of > VAR_DECL args. > > for gcc/ChangeLog > > PR c++/88534 > PR c++/88537 > * g++.dg/cpp2a/pr88534.C: New. > * g++.dg/cpp2a/pr88537.C: New. > --- > gcc/dwarf2out.c | 7 ++++ > gcc/testsuite/g++.dg/cpp2a/pr88534.C | 65 ++++++++++++++++++++++++++++++++++ > gcc/testsuite/g++.dg/cpp2a/pr88537.C | 16 ++++++++ > 3 files changed, 88 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88534.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88537.C > > diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > index 8305555681447..478d9b9b289b1 100644 > --- a/gcc/dwarf2out.c > +++ b/gcc/dwarf2out.c > @@ -13601,6 +13601,13 @@ generic_parameter_die (tree parm, tree arg, > dw_die_ref tmpl_die = NULL; > const char *name = NULL; > > + /* C++2a accepts class literals as template parameters, and var > + decls with initializers represent them. The VAR_DECLs would be > + rejected, but we can take the DECL_INITIAL constructor and > + attempt to expand it. */ > + if (TREE_CODE (arg) == VAR_DECL) You can use VAR_P for this. Marek ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-14 20:22 ` Marek Polacek @ 2019-03-14 20:33 ` Jason Merrill 2019-03-15 13:57 ` Alexandre Oliva 0 siblings, 1 reply; 18+ messages in thread From: Jason Merrill @ 2019-03-14 20:33 UTC (permalink / raw) To: Marek Polacek, Alexandre Oliva; +Cc: gcc-patches, nathan, ccoutant On 3/14/19 4:20 PM, Marek Polacek wrote: > On Thu, Mar 14, 2019 at 05:14:49PM -0300, Alexandre Oliva wrote: >> P0732R2 / C++ 2a introduce class literals as template parameters. The >> front-end uses VAR_DECLs constructed from such literals to bind the >> template PARM_DECLs, but dwarf2out.c used to reject such VAR_DECLs. >> >> Taking DECL_INITIAL from such VAR_DECLs enables the generation of >> DW_AT_const_value for them, at least when the class literal can >> actually be represented as such. >> >> Regstrapped on x86_64- and i686-linux-gnu. Ok to install? >> >> >> for gcc/ChangeLog >> >> PR c++/88534 >> PR c++/88537 >> * dwarf2out.c (generic_parameter_die): Follow DECL_INITIAL of >> VAR_DECL args. >> >> for gcc/ChangeLog >> >> PR c++/88534 >> PR c++/88537 >> * g++.dg/cpp2a/pr88534.C: New. >> * g++.dg/cpp2a/pr88537.C: New. >> --- >> gcc/dwarf2out.c | 7 ++++ >> gcc/testsuite/g++.dg/cpp2a/pr88534.C | 65 ++++++++++++++++++++++++++++++++++ >> gcc/testsuite/g++.dg/cpp2a/pr88537.C | 16 ++++++++ >> 3 files changed, 88 insertions(+) >> create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88534.C >> create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88537.C >> >> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c >> index 8305555681447..478d9b9b289b1 100644 >> --- a/gcc/dwarf2out.c >> +++ b/gcc/dwarf2out.c >> @@ -13601,6 +13601,13 @@ generic_parameter_die (tree parm, tree arg, >> dw_die_ref tmpl_die = NULL; >> const char *name = NULL; >> >> + /* C++2a accepts class literals as template parameters, and var >> + decls with initializers represent them. The VAR_DECLs would be >> + rejected, but we can take the DECL_INITIAL constructor and >> + attempt to expand it. */ >> + if (TREE_CODE (arg) == VAR_DECL) > > You can use VAR_P for this. OK with that change. Jason ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-14 20:33 ` Jason Merrill @ 2019-03-15 13:57 ` Alexandre Oliva 2019-03-20 17:13 ` Marek Polacek 0 siblings, 1 reply; 18+ messages in thread From: Alexandre Oliva @ 2019-03-15 13:57 UTC (permalink / raw) To: Jason Merrill; +Cc: Marek Polacek, gcc-patches, nathan, ccoutant On Mar 14, 2019, Jason Merrill <jason@redhat.com> wrote: >> You can use VAR_P for this. > OK with that change. Thanks, I went ahead and also added a test before dereferencing it, since there was evidence shortly thereafter that it could possibly be NULL. Here's what I'm installing. P0732R2 / C++ 2a introduce class literals as template parameters. The front-end uses VAR_DECLs constructed from such literals to bind the template PARM_DECLs, but dwarf2out.c used to reject such VAR_DECLs. Taking DECL_INITIAL from such VAR_DECLs enables the generation of DW_AT_const_value for them, at least when the class literal can actually be represented as such. for gcc/ChangeLog PR c++/88534 PR c++/88537 * dwarf2out.c (generic_parameter_die): Follow DECL_INITIAL of VAR_DECL args. for gcc/ChangeLog PR c++/88534 PR c++/88537 * g++.dg/cpp2a/pr88534.C: New. * g++.dg/cpp2a/pr88537.C: New. --- gcc/dwarf2out.c | 7 ++++ gcc/testsuite/g++.dg/cpp2a/pr88534.C | 65 ++++++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/pr88537.C | 16 ++++++++ 3 files changed, 88 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88534.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/pr88537.C diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index d9cefd3e1d3cf..251fff7b9ae96 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -13603,6 +13603,13 @@ generic_parameter_die (tree parm, tree arg, dw_die_ref tmpl_die = NULL; const char *name = NULL; + /* C++2a accepts class literals as template parameters, and var + decls with initializers represent them. The VAR_DECLs would be + rejected, but we can take the DECL_INITIAL constructor and + attempt to expand it. */ + if (arg && VAR_P (arg)) + arg = DECL_INITIAL (arg); + if (!parm || !DECL_NAME (parm) || !arg) return NULL; diff --git a/gcc/testsuite/g++.dg/cpp2a/pr88534.C b/gcc/testsuite/g++.dg/cpp2a/pr88534.C new file mode 100644 index 0000000000000..54faf385f11aa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr88534.C @@ -0,0 +1,65 @@ +// { dg-do compile { target c++2a } } +// { dg-options "-g" } + +typedef __SIZE_TYPE__ size_t; + +namespace std +{ + +template <typename T, T... I> +struct integer_sequence +{ + typedef T value_type; + static constexpr size_t size () noexcept { return sizeof...(I); } +}; + +template <typename T, T N> +using make_integer_sequence = integer_sequence<T, __integer_pack (N)...>; + +template <size_t... I> +using index_sequence = integer_sequence<size_t, I...>; + +template <size_t N> +using make_index_sequence = make_integer_sequence<size_t, N>; +} + +template <typename T, size_t N> struct S +{ + T content[N]; + using char_type = T; + template <size_t... I> + constexpr S (const T (&input)[N], std::index_sequence<I...>) noexcept : content{input[I]...} { } + constexpr S (const T (&input)[N]) noexcept : S (input, std::make_index_sequence<N> ()) { } + constexpr size_t size () const noexcept + { + if (content[N - 1] == '\0') + return N - 1; + else + return N; + } + constexpr T operator[] (size_t i) const noexcept + { + return content[i]; + } + constexpr const T *begin () const noexcept + { + return content; + } + constexpr const T *end () const noexcept + { + return content + size (); + } +}; + +template <typename T, size_t N> S (const T (&)[N]) -> S<T, N>; + +template <S S> +struct F +{ +}; + +auto +foo () +{ + F<"test"> f; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/pr88537.C b/gcc/testsuite/g++.dg/cpp2a/pr88537.C new file mode 100644 index 0000000000000..d558d45f57830 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/pr88537.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++2a } } +// { dg-options "-g" } + +struct pair { + unsigned a; + unsigned b; + constexpr pair(unsigned _a, unsigned _b) noexcept: a{_a}, b{_b} { } +}; + +template <pair p> void fnc() { + +} + +void f() { + fnc<pair(10,20)>(); +} -- Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jamás-GNUChe ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-15 13:57 ` Alexandre Oliva @ 2019-03-20 17:13 ` Marek Polacek 2019-03-20 20:05 ` Alexandre Oliva 0 siblings, 1 reply; 18+ messages in thread From: Marek Polacek @ 2019-03-20 17:13 UTC (permalink / raw) To: Alexandre Oliva; +Cc: Jason Merrill, gcc-patches, nathan On Fri, Mar 15, 2019 at 10:53:35AM -0300, Alexandre Oliva wrote: > On Mar 14, 2019, Jason Merrill <jason@redhat.com> wrote: > > >> You can use VAR_P for this. > > > OK with that change. > > Thanks, I went ahead and also added a test before dereferencing it, > since there was evidence shortly thereafter that it could possibly be > NULL. > > Here's what I'm installing. > > > P0732R2 / C++ 2a introduce class literals as template parameters. The > front-end uses VAR_DECLs constructed from such literals to bind the > template PARM_DECLs, but dwarf2out.c used to reject such VAR_DECLs. > > Taking DECL_INITIAL from such VAR_DECLs enables the generation of > DW_AT_const_value for them, at least when the class literal can > actually be represented as such. > > > for gcc/ChangeLog > > PR c++/88534 > PR c++/88537 > * dwarf2out.c (generic_parameter_die): Follow DECL_INITIAL of > VAR_DECL args. > > for gcc/ChangeLog > > PR c++/88534 > PR c++/88537 > * g++.dg/cpp2a/pr88534.C: New. This test fails with pr88534.C:58:1: sorry, unimplemented: string literal in function template signature Marek ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-20 17:13 ` Marek Polacek @ 2019-03-20 20:05 ` Alexandre Oliva 2019-03-20 21:58 ` Marek Polacek 0 siblings, 1 reply; 18+ messages in thread From: Alexandre Oliva @ 2019-03-20 20:05 UTC (permalink / raw) To: Marek Polacek; +Cc: Jason Merrill, gcc-patches, nathan On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: > This test fails with > pr88534.C:58:1: sorry, unimplemented: string literal in function template signature Interesting... gcc-8 rejected it with an error message rejecting the template parameter, but my latest trunk build (dated Mar 13, r269641) compiles it all right. Was there a subsequent fix, maybe? I didn't realize it was supposed to be rejected. -- Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jamás-GNUChe ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-20 20:05 ` Alexandre Oliva @ 2019-03-20 21:58 ` Marek Polacek 2019-03-20 22:06 ` Jakub Jelinek 0 siblings, 1 reply; 18+ messages in thread From: Marek Polacek @ 2019-03-20 21:58 UTC (permalink / raw) To: Alexandre Oliva; +Cc: Jason Merrill, gcc-patches, nathan, Martin Sebor On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: > On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: > > > This test fails with > > pr88534.C:58:1: sorry, unimplemented: string literal in function template signature > > Interesting... gcc-8 rejected it with an error message rejecting the > template parameter, but my latest trunk build (dated Mar 13, r269641) > compiles it all right. Was there a subsequent fix, maybe? I didn't > realize it was supposed to be rejected. Ah, that problem only started with r269814, namely this hunk: --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -824,10 +824,9 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags) value = digest_init_flags (type, init, flags, tf_warning_or_error); } - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_STRING_FLAG (TREE_TYPE (type)) - && TREE_CODE (value) == CONSTRUCTOR) - value = braced_list_to_string (type, value); + /* Look for braced array initializers for character arrays and + recursively convert them into STRING_CSTs. */ + value = braced_lists_to_strings (type, value); current_ref_temp_count = 0; value = extend_ref_init_temps (decl, value, cleanups); which now changes {.content={116, 101, 115, 116, 0}} to {.content="test"} Marek ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-20 21:58 ` Marek Polacek @ 2019-03-20 22:06 ` Jakub Jelinek 2019-03-20 22:20 ` Marek Polacek 0 siblings, 1 reply; 18+ messages in thread From: Jakub Jelinek @ 2019-03-20 22:06 UTC (permalink / raw) To: Marek Polacek Cc: Alexandre Oliva, Jason Merrill, gcc-patches, nathan, Martin Sebor On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: > On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: > > On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: > > > > > This test fails with > > > pr88534.C:58:1: sorry, unimplemented: string literal in function template signature > > > > Interesting... gcc-8 rejected it with an error message rejecting the > > template parameter, but my latest trunk build (dated Mar 13, r269641) > > compiles it all right. Was there a subsequent fix, maybe? I didn't > > realize it was supposed to be rejected. > > Ah, that problem only started with r269814, namely this hunk: Maybe this is done too early and should be postponed to genericization (perhaps except for TREE_STATIC vars)? > --- a/gcc/cp/typeck2.c > +++ b/gcc/cp/typeck2.c > @@ -824,10 +824,9 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags) > value = digest_init_flags (type, init, flags, tf_warning_or_error); > } > > - if (TREE_CODE (type) == ARRAY_TYPE > - && TYPE_STRING_FLAG (TREE_TYPE (type)) > - && TREE_CODE (value) == CONSTRUCTOR) > - value = braced_list_to_string (type, value); > + /* Look for braced array initializers for character arrays and > + recursively convert them into STRING_CSTs. */ > + value = braced_lists_to_strings (type, value); > > current_ref_temp_count = 0; > value = extend_ref_init_temps (decl, value, cleanups); > > which now changes > > {.content={116, 101, 115, 116, 0}} > > to > > {.content="test"} > > Marek Jakub ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-20 22:06 ` Jakub Jelinek @ 2019-03-20 22:20 ` Marek Polacek 2019-03-21 19:12 ` Jason Merrill 0 siblings, 1 reply; 18+ messages in thread From: Marek Polacek @ 2019-03-20 22:20 UTC (permalink / raw) To: Jakub Jelinek Cc: Alexandre Oliva, Jason Merrill, gcc-patches, nathan, Martin Sebor On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: > On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: > > On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: > > > On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: > > > > > > > This test fails with > > > > pr88534.C:58:1: sorry, unimplemented: string literal in function template signature > > > > > > Interesting... gcc-8 rejected it with an error message rejecting the > > > template parameter, but my latest trunk build (dated Mar 13, r269641) > > > compiles it all right. Was there a subsequent fix, maybe? I didn't > > > realize it was supposed to be rejected. > > > > Ah, that problem only started with r269814, namely this hunk: > > Maybe this is done too early and should be postponed to genericization > (perhaps except for TREE_STATIC vars)? Or skip when DECL is template_parm_object_p. > > --- a/gcc/cp/typeck2.c > > +++ b/gcc/cp/typeck2.c > > @@ -824,10 +824,9 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags) > > value = digest_init_flags (type, init, flags, tf_warning_or_error); > > } > > > > - if (TREE_CODE (type) == ARRAY_TYPE > > - && TYPE_STRING_FLAG (TREE_TYPE (type)) > > - && TREE_CODE (value) == CONSTRUCTOR) > > - value = braced_list_to_string (type, value); > > + /* Look for braced array initializers for character arrays and > > + recursively convert them into STRING_CSTs. */ > > + value = braced_lists_to_strings (type, value); > > > > current_ref_temp_count = 0; > > value = extend_ref_init_temps (decl, value, cleanups); > > > > which now changes > > > > {.content={116, 101, 115, 116, 0}} > > > > to > > > > {.content="test"} Marek ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-20 22:20 ` Marek Polacek @ 2019-03-21 19:12 ` Jason Merrill 2019-03-27 11:06 ` Jonathan Wakely 2019-03-27 17:02 ` Martin Sebor 0 siblings, 2 replies; 18+ messages in thread From: Jason Merrill @ 2019-03-21 19:12 UTC (permalink / raw) To: Marek Polacek, Jakub Jelinek Cc: Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/20/19 6:06 PM, Marek Polacek wrote: > On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>> >>>>> This test fails with >>>>> pr88534.C:58:1: sorry, unimplemented: string literal in function template signature >>>> >>>> Interesting... gcc-8 rejected it with an error message rejecting the >>>> template parameter, but my latest trunk build (dated Mar 13, r269641) >>>> compiles it all right. Was there a subsequent fix, maybe? I didn't >>>> realize it was supposed to be rejected. >>> >>> Ah, that problem only started with r269814, namely this hunk: >> >> Maybe this is done too early and should be postponed to genericization >> (perhaps except for TREE_STATIC vars)? > > Or skip when DECL is template_parm_object_p. Or handle it in mangle.c. I don't see any reason we shouldn't accept struct A { char c[4]; }; template <A a> struct B { }; B<A{"FOO"}> b; Probably we should use the same mangling whether the initializer for c was spelled as a string literal or list of integers. The thing we still don't want to allow is mangling the *address* of a string literal. Jason ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-21 19:12 ` Jason Merrill @ 2019-03-27 11:06 ` Jonathan Wakely 2019-03-27 21:36 ` Martin Sebor 2019-03-27 17:02 ` Martin Sebor 1 sibling, 1 reply; 18+ messages in thread From: Jonathan Wakely @ 2019-03-27 11:06 UTC (permalink / raw) To: Jason Merrill Cc: Marek Polacek, Jakub Jelinek, Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 21/03/19 15:03 -0400, Jason Merrill wrote: >On 3/20/19 6:06 PM, Marek Polacek wrote: >>On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>> >>>>>>This test fails with >>>>>>pr88534.C:58:1: sorry, unimplemented: string literal in function template signature >>>>> >>>>>Interesting... gcc-8 rejected it with an error message rejecting the >>>>>template parameter, but my latest trunk build (dated Mar 13, r269641) >>>>>compiles it all right. Was there a subsequent fix, maybe? I didn't >>>>>realize it was supposed to be rejected. >>>> >>>>Ah, that problem only started with r269814, namely this hunk: >>> >>>Maybe this is done too early and should be postponed to genericization >>>(perhaps except for TREE_STATIC vars)? >> >>Or skip when DECL is template_parm_object_p. > >Or handle it in mangle.c. I don't see any reason we shouldn't accept > >struct A >{ > char c[4]; >}; > >template <A a> struct B { }; >B<A{"FOO"}> b; > >Probably we should use the same mangling whether the initializer for c >was spelled as a string literal or list of integers. > >The thing we still don't want to allow is mangling the *address* of a >string literal. Will that help PR 47488 as well? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-27 11:06 ` Jonathan Wakely @ 2019-03-27 21:36 ` Martin Sebor 2019-03-28 6:47 ` Martin Sebor 0 siblings, 1 reply; 18+ messages in thread From: Martin Sebor @ 2019-03-27 21:36 UTC (permalink / raw) To: Jonathan Wakely, Jason Merrill Cc: Marek Polacek, Jakub Jelinek, Alexandre Oliva, gcc-patches, nathan, Martin Sebor [-- Attachment #1: Type: text/plain, Size: 2518 bytes --] On 3/27/19 4:44 AM, Jonathan Wakely wrote: > On 21/03/19 15:03 -0400, Jason Merrill wrote: >> On 3/20/19 6:06 PM, Marek Polacek wrote: >>> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>>> >>>>>>> This test fails with >>>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in function >>>>>>> template signature >>>>>> >>>>>> Interesting... gcc-8 rejected it with an error message rejecting the >>>>>> template parameter, but my latest trunk build (dated Mar 13, r269641) >>>>>> compiles it all right. Was there a subsequent fix, maybe? I didn't >>>>>> realize it was supposed to be rejected. >>>>> >>>>> Ah, that problem only started with r269814, namely this hunk: >>>> >>>> Maybe this is done too early and should be postponed to genericization >>>> (perhaps except for TREE_STATIC vars)? >>> >>> Or skip when DECL is template_parm_object_p. >> >> Or handle it in mangle.c. I don't see any reason we shouldn't accept >> >> struct A >> { >>  char c[4]; >> }; >> >> template <A a> struct B { }; >> B<A{"FOO"}> b; >> >> Probably we should use the same mangling whether the initializer for c >> was spelled as a string literal or list of integers. >> >> The thing we still don't want to allow is mangling the *address* of a >> string literal. > > Will that help PR 47488 as well? What I have (attached) accepts all three test cases from PR 47488 (comment #0, #1, #2, and #5) but with different mangling. The difference in the mangling of the function in the test case in comment #0 is Clang: _Z1gIiEDTcl1fcvT__ELA1_KcEEERKS0_ GCC 9: _Z1gIiEDTcl1fcvT__ELKc0EEERKS0_ I'm not very familiar with the C++ ABI mangling but from what I can tell, Clang treats the type as a literal array of 1 const char element (LA1_Kc) without actually encoding its value, while with my patch GCC encodes it as a constant literal initializer consisting of 1 null char (LKc0). In other words, Clang would mangle these two the same for the same T: template < typename T > decltype (f (T(), "123")) g (const T&); template < typename T > decltype (f (T(), "abc")) g (const T&); while GCC would mangle them differently. Which is correct? Clang's seems correct in this case but would it also be correct to mangle Jason's B<A{"FOO"}> the same as B<A{"BAR"}>? Martin [-- Attachment #2: gcc-89833.diff --] [-- Type: text/x-patch, Size: 1732 bytes --] PR c++/89833 - sorry, unimplemented: string literal in function template signature gcc/cp/ChangeLog: PR c++/89833 * mangle.c (write_expression): Convert braced initializer lists to STRING_CSTs. (write_template_arg_literal): Mangle strings the same as braced initializer lists. Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 269965) +++ gcc/cp/mangle.c (working copy) @@ -3136,6 +3136,10 @@ write_expression (tree expr) } else if (code == CONSTRUCTOR) { + /* Convert braced initializer lists to STRING_CSTs so that + A<"Foo"> and A<{'F', 'o', 'o', 0}> mangle the same. */ + expr = braced_lists_to_strings (TREE_TYPE (expr), expr); + vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr); unsigned i; tree val; @@ -3354,8 +3358,13 @@ static void write_template_arg_literal (const tree value) { write_char ('L'); - write_type (TREE_TYPE (value)); + tree valtype = TREE_TYPE (value); + if (TREE_CODE (value) == STRING_CST) + valtype = TREE_TYPE (valtype); + + write_type (valtype); + /* Write a null member pointer value as (type)0, regardless of its real representation. */ if (null_member_pointer_value_p (value)) @@ -3397,7 +3406,15 @@ write_template_arg_literal (const tree value) break; case STRING_CST: - sorry ("string literal in function template signature"); + /* Mangle strings the same as braced initializer lists. */ + for (const char *p = TREE_STRING_POINTER (value); ; ++p) + { + write_unsigned_number (*(const unsigned char*)p); + if (!*p) + break; + write_string ("EL"); + write_type (valtype); + } break; default: ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-27 21:36 ` Martin Sebor @ 2019-03-28 6:47 ` Martin Sebor 2019-03-28 17:49 ` Jason Merrill 0 siblings, 1 reply; 18+ messages in thread From: Martin Sebor @ 2019-03-28 6:47 UTC (permalink / raw) To: Jonathan Wakely, Jason Merrill Cc: Marek Polacek, Jakub Jelinek, Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/27/19 3:11 PM, Martin Sebor wrote: > On 3/27/19 4:44 AM, Jonathan Wakely wrote: >> On 21/03/19 15:03 -0400, Jason Merrill wrote: >>> On 3/20/19 6:06 PM, Marek Polacek wrote: >>>> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>>>> >>>>>>>> This test fails with >>>>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in function >>>>>>>> template signature >>>>>>> >>>>>>> Interesting... gcc-8 rejected it with an error message rejecting >>>>>>> the >>>>>>> template parameter, but my latest trunk build (dated Mar 13, >>>>>>> r269641) >>>>>>> compiles it all right. Was there a subsequent fix, maybe? I didn't >>>>>>> realize it was supposed to be rejected. >>>>>> >>>>>> Ah, that problem only started with r269814, namely this hunk: >>>>> >>>>> Maybe this is done too early and should be postponed to genericization >>>>> (perhaps except for TREE_STATIC vars)? >>>> >>>> Or skip when DECL is template_parm_object_p. >>> >>> Or handle it in mangle.c. I don't see any reason we shouldn't accept >>> >>> struct A >>> { >>>  char c[4]; >>> }; >>> >>> template <A a> struct B { }; >>> B<A{"FOO"}> b; >>> >>> Probably we should use the same mangling whether the initializer for >>> c was spelled as a string literal or list of integers. >>> >>> The thing we still don't want to allow is mangling the *address* of a >>> string literal. >> >> Will that help PR 47488 as well? > > What I have (attached) accepts all three test cases from PR 47488 > (comment #0, #1, #2, and #5) but with different mangling. > > The difference in the mangling of the function in the test case > in comment #0 is > >  Clang: _Z1gIiEDTcl1fcvT__ELA1_KcEEERKS0_ >  GCC 9: _Z1gIiEDTcl1fcvT__ELKc0EEERKS0_ > > I'm not very familiar with the C++ ABI mangling but from what > I can tell, Clang treats the type as a literal array of 1 const > char element (LA1_Kc) without actually encoding its value, while > with my patch GCC encodes it as a constant literal initializer > consisting of 1 null char (LKc0). In other words, Clang would > mangle these two the same for the same T: > >  template < typename T > >  decltype (f (T(), "123")) g (const T&); > >  template < typename T > >  decltype (f (T(), "abc")) g (const T&); > > while GCC would mangle them differently. > > Which is correct? Clang's seems correct in this case but would > it also be correct to mangle Jason's B<A{"FOO"}> the same as > B<A{"BAR"}>? After some poking around I found the issue below that seems to answer the question at least for Jason's example: https://github.com/itanium-cxx-abi/cxx-abi/issues/64 But this is an open issue that leaves some other questions unanswered, mainly that of the exact encoding of the literal (the length of the directly encoded subsequence and the hash algorithm to compute the hash value of the string). In any event, using the same encoding as for initializer lists (i.e., (elt-type, elt-value)...) doesn't follow this approach. Should I prototype the solution outlined in the issue for GCC 9? I suppose there's still the question of compatibility between initializer lists and string literals, namely whether this B<A{"123"}> is supposed to mangle the same as B<A{'1', '2', '3', 0}> The ABI issue only talks about string literals and not braced initializer lists. I see in Revision History [150204] Add mangling for braced initializer lists, so presumably there is a difference, but I can't find what it is. Martin ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-28 6:47 ` Martin Sebor @ 2019-03-28 17:49 ` Jason Merrill 2019-03-29 0:07 ` Martin Sebor 0 siblings, 1 reply; 18+ messages in thread From: Jason Merrill @ 2019-03-28 17:49 UTC (permalink / raw) To: Martin Sebor, Jonathan Wakely Cc: Marek Polacek, Jakub Jelinek, Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/27/19 6:56 PM, Martin Sebor wrote: > On 3/27/19 3:11 PM, Martin Sebor wrote: >> On 3/27/19 4:44 AM, Jonathan Wakely wrote: >>> On 21/03/19 15:03 -0400, Jason Merrill wrote: >>>> On 3/20/19 6:06 PM, Marek Polacek wrote: >>>>> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>>>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>>>>> >>>>>>>>> This test fails with >>>>>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in >>>>>>>>> function template signature >>>>>>>> >>>>>>>> Interesting... gcc-8 rejected it with an error message >>>>>>>> rejecting the >>>>>>>> template parameter, but my latest trunk build (dated Mar 13, >>>>>>>> r269641) >>>>>>>> compiles it all right. Was there a subsequent fix, maybe? I >>>>>>>> didn't >>>>>>>> realize it was supposed to be rejected. >>>>>>> >>>>>>> Ah, that problem only started with r269814, namely this hunk: >>>>>> >>>>>> Maybe this is done too early and should be postponed to >>>>>> genericization >>>>>> (perhaps except for TREE_STATIC vars)? >>>>> >>>>> Or skip when DECL is template_parm_object_p. >>>> >>>> Or handle it in mangle.c. I don't see any reason we shouldn't accept >>>> >>>> struct A >>>> { >>>>  char c[4]; >>>> }; >>>> >>>> template <A a> struct B { }; >>>> B<A{"FOO"}> b; >>>> >>>> Probably we should use the same mangling whether the initializer for >>>> c was spelled as a string literal or list of integers. >>>> >>>> The thing we still don't want to allow is mangling the *address* of >>>> a string literal. >>> >>> Will that help PR 47488 as well? >> >> What I have (attached) accepts all three test cases from PR 47488 >> (comment #0, #1, #2, and #5) but with different mangling. >> >> The difference in the mangling of the function in the test case >> in comment #0 is >> >>   Clang: _Z1gIiEDTcl1fcvT__ELA1_KcEEERKS0_ >>   GCC 9: _Z1gIiEDTcl1fcvT__ELKc0EEERKS0_ >> >> I'm not very familiar with the C++ ABI mangling but from what >> I can tell, Clang treats the type as a literal array of 1 const >> char element (LA1_Kc) without actually encoding its value, while >> with my patch GCC encodes it as a constant literal initializer >> consisting of 1 null char (LKc0). In other words, Clang would >> mangle these two the same for the same T: >> >>   template < typename T > >>   decltype (f (T(), "123")) g (const T&); >> >>   template < typename T > >>   decltype (f (T(), "abc")) g (const T&); >> >> while GCC would mangle them differently. >> >> Which is correct? Clang's seems correct in this case but would >> it also be correct to mangle Jason's B<A{"FOO"}> the same as >> B<A{"BAR"}>? > > After some poking around I found the issue below that seems > to answer the question at least for Jason's example: > >  https://github.com/itanium-cxx-abi/cxx-abi/issues/64 > > But this is an open issue that leaves some other questions > unanswered, mainly that of the exact encoding of the literal > (the length of the directly encoded subsequence and the hash > algorithm to compute the hash value of the string). > > In any event, using the same encoding as for initializer > lists (i.e., (elt-type, elt-value)...) doesn't follow this > approach. > > Should I prototype the solution outlined in the issue for > GCC 9? I think let's leave that for the future, and use the aggregate encoding for GCC 9. > I suppose there's still the question of compatibility between > initializer lists and string literals, namely whether this > >  B<A{"123"}> > > is supposed to mangle the same as > >  B<A{'1', '2', '3', 0}> > > The ABI issue only talks about string literals and not braced > initializer lists. I see in Revision History [150204] Add > mangling for braced initializer lists, so presumably there > is a difference, but I can't find what it is. The issue for mangling template arguments of class type is https://github.com/itanium-cxx-abi/cxx-abi/issues/63 The mangling of braced-init-lists is # type {expr-list}, conversion with braced-init-list argument ::= tl <type> <braced-expression>* E # {expr-list}, braced-init-list in any other context ::= il <braced-expression>* E Your patch doesn't use this mangling. Here's a variant of my example that actually causes these to show up in the mangling: struct A { char c[4]; }; template <A a> struct B { }; void f(B<A{"FOO"}>) {} void g(B<A{'F', 'O', 'O', '\0'}>) {} Jason ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-28 17:49 ` Jason Merrill @ 2019-03-29 0:07 ` Martin Sebor 2019-03-29 15:08 ` Jason Merrill 0 siblings, 1 reply; 18+ messages in thread From: Martin Sebor @ 2019-03-29 0:07 UTC (permalink / raw) To: Jason Merrill, Jonathan Wakely Cc: Marek Polacek, Jakub Jelinek, Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/28/19 11:45 AM, Jason Merrill wrote: > On 3/27/19 6:56 PM, Martin Sebor wrote: >> On 3/27/19 3:11 PM, Martin Sebor wrote: >>> On 3/27/19 4:44 AM, Jonathan Wakely wrote: >>>> On 21/03/19 15:03 -0400, Jason Merrill wrote: >>>>> On 3/20/19 6:06 PM, Marek Polacek wrote: >>>>>> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>>>>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>>>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>>>>>> >>>>>>>>>> This test fails with >>>>>>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in >>>>>>>>>> function template signature >>>>>>>>> >>>>>>>>> Interesting... gcc-8 rejected it with an error message >>>>>>>>> rejecting the >>>>>>>>> template parameter, but my latest trunk build (dated Mar 13, >>>>>>>>> r269641) >>>>>>>>> compiles it all right. Was there a subsequent fix, maybe? I >>>>>>>>> didn't >>>>>>>>> realize it was supposed to be rejected. >>>>>>>> >>>>>>>> Ah, that problem only started with r269814, namely this hunk: >>>>>>> >>>>>>> Maybe this is done too early and should be postponed to >>>>>>> genericization >>>>>>> (perhaps except for TREE_STATIC vars)? >>>>>> >>>>>> Or skip when DECL is template_parm_object_p. >>>>> >>>>> Or handle it in mangle.c. I don't see any reason we shouldn't accept >>>>> >>>>> struct A >>>>> { >>>>>  char c[4]; >>>>> }; >>>>> >>>>> template <A a> struct B { }; >>>>> B<A{"FOO"}> b; >>>>> >>>>> Probably we should use the same mangling whether the initializer >>>>> for c was spelled as a string literal or list of integers. >>>>> >>>>> The thing we still don't want to allow is mangling the *address* of >>>>> a string literal. >>>> >>>> Will that help PR 47488 as well? >>> >>> What I have (attached) accepts all three test cases from PR 47488 >>> (comment #0, #1, #2, and #5) but with different mangling. >>> >>> The difference in the mangling of the function in the test case >>> in comment #0 is >>> >>>   Clang: _Z1gIiEDTcl1fcvT__ELA1_KcEEERKS0_ >>>   GCC 9: _Z1gIiEDTcl1fcvT__ELKc0EEERKS0_ >>> >>> I'm not very familiar with the C++ ABI mangling but from what >>> I can tell, Clang treats the type as a literal array of 1 const >>> char element (LA1_Kc) without actually encoding its value, while >>> with my patch GCC encodes it as a constant literal initializer >>> consisting of 1 null char (LKc0). In other words, Clang would >>> mangle these two the same for the same T: >>> >>>   template < typename T > >>>   decltype (f (T(), "123")) g (const T&); >>> >>>   template < typename T > >>>   decltype (f (T(), "abc")) g (const T&); >>> >>> while GCC would mangle them differently. >>> >>> Which is correct? Clang's seems correct in this case but would >>> it also be correct to mangle Jason's B<A{"FOO"}> the same as >>> B<A{"BAR"}>? >> >> After some poking around I found the issue below that seems >> to answer the question at least for Jason's example: >> >>   https://github.com/itanium-cxx-abi/cxx-abi/issues/64 >> >> But this is an open issue that leaves some other questions >> unanswered, mainly that of the exact encoding of the literal >> (the length of the directly encoded subsequence and the hash >> algorithm to compute the hash value of the string). >> >> In any event, using the same encoding as for initializer >> lists (i.e., (elt-type, elt-value)...) doesn't follow this >> approach. >> >> Should I prototype the solution outlined in the issue for >> GCC 9? > > I think let's leave that for the future, and use the aggregate encoding > for GCC 9. > >> I suppose there's still the question of compatibility between >> initializer lists and string literals, namely whether this >> >>   B<A{"123"}> >> >> is supposed to mangle the same as >> >>   B<A{'1', '2', '3', 0}> >> >> The ABI issue only talks about string literals and not braced >> initializer lists. I see in Revision History [150204] Add >> mangling for braced initializer lists, so presumably there >> is a difference, but I can't find what it is. > > The issue for mangling template arguments of class type is > >  https://github.com/itanium-cxx-abi/cxx-abi/issues/63 Whoops. Off-by-one error. Thanks! > > The mangling of braced-init-lists is > > # type {expr-list}, conversion with braced-init-list argument > ::= tl <type> <braced-expression>* E > > # {expr-list}, braced-init-list in any other context > ::= il <braced-expression>* E > > Your patch doesn't use this mangling. Here's a variant of my example > that actually causes these to show up in the mangling: > > struct A { char c[4]; }; > template <A a> struct B { }; > void f(B<A{"FOO"}>) {} > void g(B<A{'F', 'O', 'O', '\0'}>) {} Right, that's also what I'm testing. There are few interesting variations. Given struct A { char c[5]; }; all of these are equivalent and so should mangle the same: void f (B<A{"a\0b"}>) {} void f (B<A{"a\0b\0"}>) {} void f (B<A{ {'a', 0, 'b'}>) {} void f (B<A{ {'a', 0, 'b', 0}>) {} void f (B<A{ {'a', 0, 'b', 0, 0}>) {} Interior nuls need to be mangled but the trailing ones, either explicit or implicit, don't. That also needs to be specified in the ABI. I believe we also need to handle these the same, both during overloading and mangling: void f (B<A{ }>) {} void f (B<A{ 0 }>) {} void f (B<A{ 0, 0 }>) {} void f (B<A{ "" }>) {} GCC currently treats them as distinct irrespective of A's member's type. I opened bug 89878 for this since I don't expect to deal with the overloading part in this patch. Martin ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-29 0:07 ` Martin Sebor @ 2019-03-29 15:08 ` Jason Merrill 0 siblings, 0 replies; 18+ messages in thread From: Jason Merrill @ 2019-03-29 15:08 UTC (permalink / raw) To: Martin Sebor, Jonathan Wakely Cc: Marek Polacek, Jakub Jelinek, Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/28/19 7:54 PM, Martin Sebor wrote: > On 3/28/19 11:45 AM, Jason Merrill wrote: >> On 3/27/19 6:56 PM, Martin Sebor wrote: >>> On 3/27/19 3:11 PM, Martin Sebor wrote: >>>> On 3/27/19 4:44 AM, Jonathan Wakely wrote: >>>>> On 21/03/19 15:03 -0400, Jason Merrill wrote: >>>>>> On 3/20/19 6:06 PM, Marek Polacek wrote: >>>>>>> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>>>>>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>>>>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>>>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>>>>>>> >>>>>>>>>>> This test fails with >>>>>>>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in >>>>>>>>>>> function template signature >>>>>>>>>> >>>>>>>>>> Interesting... gcc-8 rejected it with an error message >>>>>>>>>> rejecting the >>>>>>>>>> template parameter, but my latest trunk build (dated Mar 13, >>>>>>>>>> r269641) >>>>>>>>>> compiles it all right. Was there a subsequent fix, maybe? I >>>>>>>>>> didn't >>>>>>>>>> realize it was supposed to be rejected. >>>>>>>>> >>>>>>>>> Ah, that problem only started with r269814, namely this hunk: >>>>>>>> >>>>>>>> Maybe this is done too early and should be postponed to >>>>>>>> genericization >>>>>>>> (perhaps except for TREE_STATIC vars)? >>>>>>> >>>>>>> Or skip when DECL is template_parm_object_p. >>>>>> >>>>>> Or handle it in mangle.c. I don't see any reason we shouldn't accept >>>>>> >>>>>> struct A >>>>>> { >>>>>>  char c[4]; >>>>>> }; >>>>>> >>>>>> template <A a> struct B { }; >>>>>> B<A{"FOO"}> b; >>>>>> >>>>>> Probably we should use the same mangling whether the initializer >>>>>> for c was spelled as a string literal or list of integers. >>>>>> >>>>>> The thing we still don't want to allow is mangling the *address* >>>>>> of a string literal. >>>>> >>>>> Will that help PR 47488 as well? >>>> >>>> What I have (attached) accepts all three test cases from PR 47488 >>>> (comment #0, #1, #2, and #5) but with different mangling. >>>> >>>> The difference in the mangling of the function in the test case >>>> in comment #0 is >>>> >>>>   Clang: _Z1gIiEDTcl1fcvT__ELA1_KcEEERKS0_ >>>>   GCC 9: _Z1gIiEDTcl1fcvT__ELKc0EEERKS0_ >>>> >>>> I'm not very familiar with the C++ ABI mangling but from what >>>> I can tell, Clang treats the type as a literal array of 1 const >>>> char element (LA1_Kc) without actually encoding its value, while >>>> with my patch GCC encodes it as a constant literal initializer >>>> consisting of 1 null char (LKc0). In other words, Clang would >>>> mangle these two the same for the same T: >>>> >>>>   template < typename T > >>>>   decltype (f (T(), "123")) g (const T&); >>>> >>>>   template < typename T > >>>>   decltype (f (T(), "abc")) g (const T&); >>>> >>>> while GCC would mangle them differently. >>>> >>>> Which is correct? Clang's seems correct in this case but would >>>> it also be correct to mangle Jason's B<A{"FOO"}> the same as >>>> B<A{"BAR"}>? >>> >>> After some poking around I found the issue below that seems >>> to answer the question at least for Jason's example: >>> >>>   https://github.com/itanium-cxx-abi/cxx-abi/issues/64 >>> >>> But this is an open issue that leaves some other questions >>> unanswered, mainly that of the exact encoding of the literal >>> (the length of the directly encoded subsequence and the hash >>> algorithm to compute the hash value of the string). >>> >>> In any event, using the same encoding as for initializer >>> lists (i.e., (elt-type, elt-value)...) doesn't follow this >>> approach. >>> >>> Should I prototype the solution outlined in the issue for >>> GCC 9? >> >> I think let's leave that for the future, and use the aggregate >> encoding for GCC 9. >> >>> I suppose there's still the question of compatibility between >>> initializer lists and string literals, namely whether this >>> >>>   B<A{"123"}> >>> >>> is supposed to mangle the same as >>> >>>   B<A{'1', '2', '3', 0}> >>> >>> The ABI issue only talks about string literals and not braced >>> initializer lists. I see in Revision History [150204] Add >>> mangling for braced initializer lists, so presumably there >>> is a difference, but I can't find what it is. >> >> The issue for mangling template arguments of class type is >> >>   https://github.com/itanium-cxx-abi/cxx-abi/issues/63 > > Whoops. Off-by-one error. Thanks! > >> >> The mangling of braced-init-lists is >> >> # type {expr-list}, conversion with braced-init-list argument >> ::= tl <type> <braced-expression>* E >> >> # {expr-list}, braced-init-list in any other context >> ::= il <braced-expression>* E >> >> Your patch doesn't use this mangling. Here's a variant of my example >> that actually causes these to show up in the mangling: >> >> struct A { char c[4]; }; >> template <A a> struct B { }; >> void f(B<A{"FOO"}>) {} >> void g(B<A{'F', 'O', 'O', '\0'}>) {} > > Right, that's also what I'm testing. There are few interesting > variations. Given > >  struct A { char c[5]; }; > > all of these are equivalent and so should mangle the same: > >  void f (B<A{"a\0b"}>) {} >  void f (B<A{"a\0b\0"}>) {} >  void f (B<A{ {'a', 0, 'b'}>) {} >  void f (B<A{ {'a', 0, 'b', 0}>) {} >  void f (B<A{ {'a', 0, 'b', 0, 0}>) {} > > Interior nuls need to be mangled but the trailing ones, either > explicit or implicit, don't. That also needs to be specified > in the ABI. Agreed, good thought. > I believe we also need to handle these the same, both during > overloading and mangling: > >  void f (B<A{ }>) {} >  void f (B<A{ 0 }>) {} >  void f (B<A{ 0, 0 }>) {} >  void f (B<A{ "" }>) {} Indeed. > GCC currently treats them as distinct irrespective of A's member's > type. I opened bug 89878 for this since I don't expect to deal > with the overloading part in this patch. Thanks. Jason ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-21 19:12 ` Jason Merrill 2019-03-27 11:06 ` Jonathan Wakely @ 2019-03-27 17:02 ` Martin Sebor 2019-03-27 21:01 ` Jason Merrill 1 sibling, 1 reply; 18+ messages in thread From: Martin Sebor @ 2019-03-27 17:02 UTC (permalink / raw) To: Jason Merrill, Marek Polacek, Jakub Jelinek Cc: Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/21/19 1:03 PM, Jason Merrill wrote: > On 3/20/19 6:06 PM, Marek Polacek wrote: >> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>> >>>>>> This test fails with >>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in function >>>>>> template signature >>>>> >>>>> Interesting... gcc-8 rejected it with an error message rejecting the >>>>> template parameter, but my latest trunk build (dated Mar 13, r269641) >>>>> compiles it all right. Was there a subsequent fix, maybe? I didn't >>>>> realize it was supposed to be rejected. >>>> >>>> Ah, that problem only started with r269814, namely this hunk: >>> >>> Maybe this is done too early and should be postponed to genericization >>> (perhaps except for TREE_STATIC vars)? >> >> Or skip when DECL is template_parm_object_p. > > Or handle it in mangle.c. I don't see any reason we shouldn't accept > > struct A > { >  char c[4]; > }; > > template <A a> struct B { }; > B<A{"FOO"}> b; > > Probably we should use the same mangling whether the initializer for c > was spelled as a string literal or list of integers. So just loop over the STRING_CST and mangle each character the same way as it were an element of the braced initializer list? Martin > > The thing we still don't want to allow is mangling the *address* of a > string literal. > > Jason ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms 2019-03-27 17:02 ` Martin Sebor @ 2019-03-27 21:01 ` Jason Merrill 0 siblings, 0 replies; 18+ messages in thread From: Jason Merrill @ 2019-03-27 21:01 UTC (permalink / raw) To: Martin Sebor, Marek Polacek, Jakub Jelinek Cc: Alexandre Oliva, gcc-patches, nathan, Martin Sebor On 3/27/19 12:24 PM, Martin Sebor wrote: > On 3/21/19 1:03 PM, Jason Merrill wrote: >> On 3/20/19 6:06 PM, Marek Polacek wrote: >>> On Wed, Mar 20, 2019 at 10:58:32PM +0100, Jakub Jelinek wrote: >>>> On Wed, Mar 20, 2019 at 05:55:04PM -0400, Marek Polacek wrote: >>>>> On Wed, Mar 20, 2019 at 04:56:33PM -0300, Alexandre Oliva wrote: >>>>>> On Mar 20, 2019, Marek Polacek <polacek@redhat.com> wrote: >>>>>> >>>>>>> This test fails with >>>>>>> pr88534.C:58:1: sorry, unimplemented: string literal in function >>>>>>> template signature >>>>>> >>>>>> Interesting... gcc-8 rejected it with an error message rejecting the >>>>>> template parameter, but my latest trunk build (dated Mar 13, r269641) >>>>>> compiles it all right. Was there a subsequent fix, maybe? I didn't >>>>>> realize it was supposed to be rejected. >>>>> >>>>> Ah, that problem only started with r269814, namely this hunk: >>>> >>>> Maybe this is done too early and should be postponed to genericization >>>> (perhaps except for TREE_STATIC vars)? >>> >>> Or skip when DECL is template_parm_object_p. >> >> Or handle it in mangle.c. I don't see any reason we shouldn't accept >> >> struct A >> { >>   char c[4]; >> }; >> >> template <A a> struct B { }; >> B<A{"FOO"}> b; >> >> Probably we should use the same mangling whether the initializer for c >> was spelled as a string literal or list of integers. > > So just loop over the STRING_CST and mangle each character the same > way as it were an element of the braced initializer list? That's probably best, yes. Jason ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2019-03-29 15:02 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-03-14 20:20 [C++ debug PATCH] [PR88534] accept VAR_DECL in class literal template parms Alexandre Oliva 2019-03-14 20:22 ` Marek Polacek 2019-03-14 20:33 ` Jason Merrill 2019-03-15 13:57 ` Alexandre Oliva 2019-03-20 17:13 ` Marek Polacek 2019-03-20 20:05 ` Alexandre Oliva 2019-03-20 21:58 ` Marek Polacek 2019-03-20 22:06 ` Jakub Jelinek 2019-03-20 22:20 ` Marek Polacek 2019-03-21 19:12 ` Jason Merrill 2019-03-27 11:06 ` Jonathan Wakely 2019-03-27 21:36 ` Martin Sebor 2019-03-28 6:47 ` Martin Sebor 2019-03-28 17:49 ` Jason Merrill 2019-03-29 0:07 ` Martin Sebor 2019-03-29 15:08 ` Jason Merrill 2019-03-27 17:02 ` Martin Sebor 2019-03-27 21:01 ` Jason Merrill
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).