aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/mangle.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-04-04 23:10:23 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-04-04 17:10:23 -0600
commit187c6369c0b4c7e013fdbe9eb08d098166359056 (patch)
tree7594a3b21feb39a649170bfa6daa218b1fdd8396 /gcc/cp/mangle.c
parent1a9b15a7d76ee3ee2cd960698a84e34ec10c2bf0 (diff)
downloadgcc-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.c79
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 ();