diff options
author | Martin Sebor <msebor@redhat.com> | 2019-04-04 23:10:23 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-04-04 17:10:23 -0600 |
commit | 187c6369c0b4c7e013fdbe9eb08d098166359056 (patch) | |
tree | 7594a3b21feb39a649170bfa6daa218b1fdd8396 /gcc/cp/mangle.c | |
parent | 1a9b15a7d76ee3ee2cd960698a84e34ec10c2bf0 (diff) | |
download | gcc-187c6369c0b4c7e013fdbe9eb08d098166359056.zip gcc-187c6369c0b4c7e013fdbe9eb08d098166359056.tar.gz gcc-187c6369c0b4c7e013fdbe9eb08d098166359056.tar.bz2 |
PR c++/89974 - ICE on a definition of a non-type specialization on a struct object with pointer to member function
PR c++/89974 - ICE on a definition of a non-type specialization on a struct object with pointer to member function
PR c++/89878 - same specializations on a zero-initialized struct object as a non-type parameter treated as distinct
PR c++/89833 - sorry, unimplemented: string literal in function template signature
PR c++/47488 - sorry, unimplemented: string literal in function template signature
gcc/cp/ChangeLog:
PR c++/89974
PR c++/89878
PR c++/89833
PR c++/47488
* decl.c (reshape_init_array_1): Strip trailing zero-initializers
from arrays of trivial type and known size.
* mangle.c (write_expression): Convert braced initializer lists
to STRING_CSTs.
(write_expression): Trim trailing zero-initializers from arrays
of trivial type.
(write_template_arg_literal): Mangle strings the same as braced
initializer lists.
gcc/testsuite/ChangeLog:
PR c++/89974
PR c++/89878
PR c++/89833
PR c++/47488
* gcc/testsuite/g++.dg/abi/mangle69.C: New test.
* gcc/testsuite/g++.dg/abi/mangle70.C: New test.
* gcc/testsuite/g++.dg/abi/mangle71.C: New test.
* gcc/testsuite/g++.dg/abi/mangle72.C: New test.
* gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C: New test.
* gcc/testsuite/g++.dg/cpp2a/nontype-class15.C: New test.
* gcc/testsuite/g++.dg/cpp2a/nontype-class16.C: New test.
* gcc/testsuite/g++.dg/init/array51.C: New test.
From-SVN: r270155
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r-- | gcc/cp/mangle.c | 79 |
1 files changed, 69 insertions, 10 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index f40c3e1..a5fd66f 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3136,18 +3136,48 @@ write_expression (tree expr) } else if (code == CONSTRUCTOR) { - vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr); - unsigned i; tree val; + bool braced_init = BRACE_ENCLOSED_INITIALIZER_P (expr); + tree etype = TREE_TYPE (expr); - if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + if (braced_init) write_string ("il"); else { write_string ("tl"); - write_type (TREE_TYPE (expr)); + write_type (etype); + } + + if (!initializer_zerop (expr) || !trivial_type_p (etype)) + { + /* Convert braced initializer lists to STRING_CSTs so that + A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while + still using the latter mangling for strings that + originated as braced initializer lists. */ + expr = braced_lists_to_strings (etype, expr); + + if (TREE_CODE (expr) == CONSTRUCTOR) + { + vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr); + unsigned last_nonzero = -1, i; + tree val; + + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + if (!initializer_zerop (val)) + last_nonzero = i; + + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + { + if (i > last_nonzero) + break; + write_expression (val); + } + } + else + { + gcc_assert (TREE_CODE (expr) == STRING_CST); + write_expression (expr); + } } - FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) - write_expression (val); write_char ('E'); } else if (code == LAMBDA_EXPR) @@ -3353,8 +3383,14 @@ write_expression (tree expr) static void write_template_arg_literal (const tree value) { - write_char ('L'); - write_type (TREE_TYPE (value)); + if (TREE_CODE (value) == STRING_CST) + /* Temporarily mangle strings as braced initializer lists. */ + write_string ("tl"); + else + write_char ('L'); + + tree valtype = TREE_TYPE (value); + write_type (valtype); /* Write a null member pointer value as (type)0, regardless of its real representation. */ @@ -3397,8 +3433,31 @@ write_template_arg_literal (const tree value) break; case STRING_CST: - sorry ("string literal in function template signature"); - break; + { + /* Mangle strings the same as braced initializer lists. */ + unsigned n = TREE_STRING_LENGTH (value); + const char *str = TREE_STRING_POINTER (value); + + /* Count the number of trailing nuls and subtract them from + STRSIZE because they don't need to be mangled. */ + for (const char *p = str + n - 1; ; --p) + { + if (*p || p == str) + { + n -= str + n - !!*p - p; + break; + } + } + tree eltype = TREE_TYPE (valtype); + for (const char *p = str; n--; ++p) + { + write_char ('L'); + write_type (eltype); + write_unsigned_number (*(const unsigned char*)p); + write_string ("E"); + } + break; + } default: gcc_unreachable (); |