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
+

Reply via email to