This is my first patch to GCC, so please let me know if I did something
wrong. This patch fixes common annoyance on w64-mingw32 targets, where
once needs to add explicit "C" linkage to make C++ app work with wmain
entry point.
* decl.c: Allow custom target implicit C linkage
* mingw-w64.h: Specify entry points with implicit C linkage
* main.C: Added implicit C linkage tests
---
gcc/config/i386/mingw-w64.h | 6 ++++++
gcc/cp/decl.c | 8 ++++++--
gcc/testsuite/g++.dg/ext/main.C | 24 ++++++++++++++++++++++++
3 files changed, 36 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/ext/main.C
diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h
index a45ce28..1ce940a 100644
--- a/gcc/config/i386/mingw-w64.h
+++ b/gcc/config/i386/mingw-w64.h
@@ -85,3 +85,9 @@ along with GCC; see the file COPYING3. If not see
%{static:-Bstatic} %{!static:-Bdynamic} \
%{shared|mdll: " SUB_LINK_ENTRY " --enable-auto-image-base} \
%(shared_libgcc_undefs)"
+
+#define CPP_IMPLICIT_TARGET_CLANG(ident) \
+ ( !strcmp(ident, "wmain") \
+ || !strcmp(ident, "DllMain") \
+ || !strcmp(ident, "WinMain") \
+ || !strcmp(ident, "wWinMain"))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a89523d..307e5c1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7290,12 +7290,16 @@ grokfndecl (tree ctype,
else if (!ctype)
DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());
- /* `main' and builtins have implicit 'C' linkage. */
+ /* `main', builtins and some target specific functions have implicit 'C' linkage. */
if ((MAIN_NAME_P (declarator)
|| (IDENTIFIER_LENGTH (declarator) > 10
&& IDENTIFIER_POINTER (declarator)[0] == '_'
&& IDENTIFIER_POINTER (declarator)[1] == '_'
- && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
+ && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)
+#ifdef CPP_IMPLICIT_TARGET_CLANG
+ || CPP_IMPLICIT_TARGET_CLANG(IDENTIFIER_POINTER (declarator))
+#endif
+ )
&& current_lang_name == lang_name_cplusplus
&& ctype == NULL_TREE
&& DECL_FILE_SCOPE_P (decl))
diff --git a/gcc/testsuite/g++.dg/ext/main.C b/gcc/testsuite/g++.dg/ext/main.C
new file mode 100644
index 0000000..4c5f1ea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/main.C
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+/* Check if entry points get implicit C linkage. If they don't, compiler will
+ * error on incompatible declarations */
+
+int main();
+extern "C" int main();
+
+#ifdef __MINGW32__
+
+int wmain();
+extern "C" int wmain();
+
+int DllMain();
+extern "C" int DllMain();
+
+int WinMain();
+extern "C" int WinMain();
+
+int wWinMain();
+extern "C" int wWinMain();
+
+#endif
+