diff options
Diffstat (limited to 'PATCHES/0014-clone_function_name_1-Retain-any-stdcall-suffix.patch')
-rw-r--r-- | PATCHES/0014-clone_function_name_1-Retain-any-stdcall-suffix.patch | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/PATCHES/0014-clone_function_name_1-Retain-any-stdcall-suffix.patch b/PATCHES/0014-clone_function_name_1-Retain-any-stdcall-suffix.patch new file mode 100644 index 0000000..e196f24 --- /dev/null +++ b/PATCHES/0014-clone_function_name_1-Retain-any-stdcall-suffix.patch @@ -0,0 +1,109 @@ +From 558617be42604d5a98938f153e990aec5b8484ed 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 | 13 ++++++++++++- + gcc/defaults.h | 2 +- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c +index 07ceb1a..a2930a0 100644 +--- a/gcc/cgraphclones.c ++++ b/gcc/cgraphclones.c +@@ -501,19 +501,30 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq, + static GTY(()) unsigned int clone_fn_id_num; + + /* Return a new assembler name for a clone with SUFFIX of a decl named +- NAME. */ ++ NAME. Final stdcall @N suffixes are maintained. */ + + tree + clone_function_name_1 (const char *name, const char *suffix) + { + size_t len = strlen (name); + char *tmp_name, *prefix; ++ const 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, clone_fn_id_num++); ++ if (at_suffix) ++ strcat (tmp_name, at_suffix); + return get_identifier (tmp_name); + } + +diff --git a/gcc/defaults.h b/gcc/defaults.h +index 3e18338..45d7192 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.7.4.windows.1 + |