commit aef7a793c2e2a942e546d8df4245495ac74d536a
Author: Jason Merrill <jason@redhat.com>
Date: Tue Jul 13 15:46:15 2010 -0400
PR c++/44540
* mangle.c (write_type): Canonicalize.
(canonicalize_for_substitution): Retain cv-quals on FUNCTION_TYPE.
(write_CV_qualifiers_for_type): Ignore them in abi>=5.
@@ -346,11 +346,19 @@ canonicalize_for_substitution (tree node)
if (TYPE_P (node)
&& TYPE_CANONICAL (node) != node
&& TYPE_MAIN_VARIANT (node) != node)
+ {
/* Here we want to strip the topmost typedef only.
We need to do that so is_std_substitution can do proper
name matching. */
- node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
- cp_type_quals (node));
+ if (TREE_CODE (node) == FUNCTION_TYPE)
+ /* Use build_qualified_type and TYPE_QUALS here to preserve
+ the old buggy mangling of attribute noreturn with abi<5. */
+ node = build_qualified_type (TYPE_MAIN_VARIANT (node),
+ TYPE_QUALS (node));
+ else
+ node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
+ cp_type_quals (node));
+ }
return node;
}
@@ -1776,6 +1784,7 @@ write_type (tree type)
if (type == error_mark_node)
return;
+ type = canonicalize_for_substitution (type);
if (find_substitution (type))
return;
@@ -1978,6 +1987,12 @@ write_CV_qualifiers_for_type (const tree type)
array. */
cp_cv_quals quals = TYPE_QUALS (type);
+ /* Attribute const/noreturn are not reflected in mangling. */
+ if (abi_version_at_least (5)
+ && (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ return 0;
+
if (quals & TYPE_QUAL_RESTRICT)
{
write_char ('r');
new file mode 100644
@@ -0,0 +1,14 @@
+// Test that attribute noreturn is not part of the mangled name.
+// { dg-options -fabi-version=0 }
+
+void baz (const char *fmt, ...);
+
+// { dg-final { scan-assembler "_Z3barPFvPKczE" } }
+void bar (void (*baz) (const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 1, 2))));
+
+void
+foo ()
+{
+ bar (&baz);
+}
new file mode 100644
@@ -0,0 +1,14 @@
+// Test for buggy mangling of attribute noreturn in abi<=4
+// { dg-options -fabi-version=4 }
+
+void baz (const char *fmt, ...);
+
+// { dg-final { scan-assembler "_Z3barPVFvPKczE" } }
+void bar (void (*baz) (const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 1, 2))));
+
+void
+foo ()
+{
+ bar (&baz);
+}