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);
+}

Reply via email to