From patchwork Tue Jul 13 22:37:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: RFC [ABI]: C++ PATCH for c++/44540 - avoid mangling attribute noreturn Date: Tue, 13 Jul 2010 12:37:18 -0000 From: Jason Merrill X-Patchwork-Id: 58822 Message-Id: <4C3CEA9E.4050102@redhat.com> To: Mark Mitchell Cc: Richard Guenther , gcc-patches List On 07/07/2010 11:14 AM, Mark Mitchell wrote: > I agree that an orthogonal improvement would be to stop abusing > TYPE_CONST and TYPE_VOLATILE for these attributes and record them on > TYPE_ATTRIBUTES. But, that would be much bigger than Jason's patch. I've done a lot of the work toward this, but decided to put it aside because it was taking up too much time for a minor internal cleanup. Perhaps I'll pick it up again after the August C++ meeting. In any case, here's the patch I'm checking in for this PR. commit aef7a793c2e2a942e546d8df4245495ac74d536a Author: Jason Merrill 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. 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/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); +}