aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-07-13 18:23:38 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-07-13 18:23:38 -0400
commit8caa8b6590d1988ab1d13ff20d1317bbdd3748fb (patch)
tree0ed2c5f3efea47a0a55677b4aabbbfe9cdd71329 /gcc
parentfcfaf838305395aff5c8caa67faa8d0ef7a4e2c6 (diff)
downloadgcc-8caa8b6590d1988ab1d13ff20d1317bbdd3748fb.zip
gcc-8caa8b6590d1988ab1d13ff20d1317bbdd3748fb.tar.gz
gcc-8caa8b6590d1988ab1d13ff20d1317bbdd3748fb.tar.bz2
re PR c++/44540 (ICE: in add_substitution, at cp/mangle.c:386 with -fkeep-inline-functions)
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. From-SVN: r162158
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/mangle.c19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/abi/noreturn1.C14
-rw-r--r--gcc/testsuite/g++.dg/abi/noreturn2.C14
5 files changed, 58 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4e2c0e4..c076929 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2010-07-13 Jason Merrill <jason@redhat.com>
+
+ 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.
+
2010-07-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/44908
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index e825952..9390a92 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -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');
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 43c73b1..b998da3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-07-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/44540
+ * g++.dg/abi/noreturn1.C: New.
+ * g++.dg/abi/noreturn2.C: New.
+
2010-07-13 Joern Rennecke <joern.rennecke@embecosm.com>
PR other/44874
diff --git a/gcc/testsuite/g++.dg/abi/noreturn1.C b/gcc/testsuite/g++.dg/abi/noreturn1.C
new file mode 100644
index 0000000..0532cf2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/noreturn1.C
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/abi/noreturn2.C b/gcc/testsuite/g++.dg/abi/noreturn2.C
new file mode 100644
index 0000000..72accaf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/noreturn2.C
@@ -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);
+}