The mangling code didn't handle complex literals, leading to a crash.
Jakub's patch implements the standard ABI mangling for them; I just
added a testcase.
Tested x86_64-pc-linux-gnu, applying to trunk. It is a regression in
4.4, 4.5, and 4.6 as well, as 4.3 gave a sorry about mangling call_expr,
but I'm reluctant to touch the mangling code in other release branches;
I think I'll just add a sorry there.
commit 68dafc7d4b8c4433ad21149ff60f64a848bef299
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Jan 16 15:18:50 2012 -0500
PR c++/51854
* mangle.c (write_template_arg_literal): Handle complex.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 15b1aca..34f19ef 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2927,6 +2927,25 @@ write_template_arg_literal (const tree value)
write_real_cst (value);
break;
+ case COMPLEX_CST:
+ if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST
+ && TREE_CODE (TREE_IMAGPART (value)) == INTEGER_CST)
+ {
+ write_integer_cst (TREE_REALPART (value));
+ write_char ('_');
+ write_integer_cst (TREE_IMAGPART (value));
+ }
+ else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST
+ && TREE_CODE (TREE_IMAGPART (value)) == REAL_CST)
+ {
+ write_real_cst (TREE_REALPART (value));
+ write_char ('_');
+ write_real_cst (TREE_IMAGPART (value));
+ }
+ else
+ gcc_unreachable ();
+ break;
+
case STRING_CST:
sorry ("string literal in function template signature");
break;
diff --git a/gcc/testsuite/g++.dg/abi/mangle60.C b/gcc/testsuite/g++.dg/abi/mangle60.C
new file mode 100644
index 0000000..f7e893a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle60.C
@@ -0,0 +1,20 @@
+// PR c++/51854
+// { dg-options "" }
+
+template <unsigned N> struct A;
+
+template <typename U, typename V>
+char foo(U, V);
+
+// { dg-final { scan-assembler "_Z3barIiEvP1AIXszcl3foocvT__ELCi0_42EEEE" } }
+template <typename U>
+void bar(A<sizeof(foo(U(), 42i))> *);
+
+// { dg-final { scan-assembler "_Z3bazIiEvP1AIXszcl3foocvT__ELCf00000000_00000000EEEE" } }
+template <typename U>
+void baz(A<sizeof(foo(U(), 0.0fj))> *);
+
+int main() {
+ bar<int>(0);
+ baz<int>(0);
+}