| From 0ca0e968bf2a79373384f8c072d08bed4f675ed9 Mon Sep 17 00:00:00 2001 |
| From: Ray Donnelly <mingw.android@gmail.com> |
| Date: Mon, 17 Aug 2015 22:57:46 +0100 |
| Subject: [PATCH] clone_function_name_1: Retain any stdcall suffix |
| |
| Previously, clone_function_name_1 would add a suffix after |
| any existing stdcall suffix, for example ipa-split.c would |
| clone test@4 as test@4.part.0. |
| |
| Later, i386_pe_strip_name_encoding_full would come along |
| and strip off everything from the last @ onwards which had |
| the effect of generating incorrect section names which |
| would then fall over with errors such as: |
| |
| error: void test() causes a section type conflict with \ |
| void test@4.part.0() |
| |
| The following testcase, reduced from Firefox can be used |
| to reproduce this. |
| |
| test.ii: |
| class ClassA { |
| public: |
| virtual int __attribute__((__stdcall__)) Dispatch() = 0; |
| }; |
| class ClassB { |
| public: |
| ClassA* __attribute__((__stdcall__)) operator->(); |
| }; |
| class ClassC : ClassA { |
| int *some_int_ptr_variable; |
| int __attribute__((__stdcall__)) Dispatch() { |
| return some_int_ptr_variable |
| ? 42 |
| : m_ClassInstanceB->Dispatch(); |
| } |
| ClassB m_ClassInstanceB; |
| }; |
| ClassC ClassInstanceC; |
| |
| Compile for i686-w64-mingw32 with: |
| cc1plus -O -fpartial-inlining -fdevirtualize \ |
| -fdevirtualize-speculatively test.ii |
| |
| Outputs: |
| test.ii: In member function 'virtual int ClassC::Dispatch()': |
| test.ii:11:36: error: virtual int ClassC::Dispatch() causes \ |
| a section type conflict with int ClassC::_ZN6ClassC8DispatchEv@4.part.0() |
| int __attribute__((CALLTYPE)) Dispatch() { |
| ^ |
| test.ii:11:36: note: \ |
| 'int ClassC::_ZN6ClassC8DispatchEv@4.part.0()' was declared here |
| --- |
| gcc/cgraphclones.c | 14 +++++++++++++- |
| gcc/defaults.h | 2 +- |
| 2 files changed, 14 insertions(+), 2 deletions(-) |
| |
| diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c |
| index 15f7e119d18..07740c4c403 100644 |
| --- a/gcc/cgraphclones.c |
| +++ b/gcc/cgraphclones.c |
| @@ -469,7 +469,8 @@ static GTY(()) hash_map<const char *, unsigned> *clone_fn_ids; |
| each NAME) unspecified number. If clone numbering is not needed |
| then the two argument clone_function_name should be used instead. |
| Should not be called directly except for by |
| - lto-partition.c:privatize_symbol_name_1. */ |
| + lto-partition.c:privatize_symbol_name_1. Final stdcall @N suffixes |
| + are maintained. */ |
| |
| tree |
| clone_function_name_numbered (const char *name, const char *suffix) |
| @@ -509,12 +510,23 @@ clone_function_name (const char *name, const char *suffix, |
| { |
| size_t len = strlen (name); |
| char *tmp_name, *prefix; |
| + char *at_suffix = NULL; |
| |
| prefix = XALLOCAVEC (char, len + strlen (suffix) + 2); |
| + /* name + 1 to skip fastcall which begins with '@' */ |
| + at_suffix = strchr (name + 1, '@'); |
| + size_t at_suffix_len = 0; |
| + if (at_suffix) |
| + { |
| + at_suffix_len = strlen (at_suffix); |
| + len -= at_suffix_len; |
| + } |
| memcpy (prefix, name, len); |
| strcpy (prefix + len + 1, suffix); |
| prefix[len] = symbol_table::symbol_suffix_separator (); |
| ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number); |
| + if (at_suffix) |
| + strcat (tmp_name, at_suffix); |
| return get_identifier (tmp_name); |
| } |
| |
| diff --git a/gcc/defaults.h b/gcc/defaults.h |
| index b7534256119..ca089ea3a04 100644 |
| --- a/gcc/defaults.h |
| +++ b/gcc/defaults.h |
| @@ -51,7 +51,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
| # define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ |
| do { const char *const name_ = (NAME); \ |
| char *const output_ = (OUTPUT) = \ |
| - (char *) alloca (strlen (name_) + 32); \ |
| + (char *) alloca (strlen (name_) + 35); \ |
| sprintf (output_, ASM_PN_FORMAT, name_, (unsigned long)(LABELNO)); \ |
| } while (0) |
| #endif |
| -- |
| 2.21.0 |
| |