[clang] [flang] [flang][Driver] Let the linker fail on multiple definitions of main() (PR #73124)

Michael Klemm via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 23 07:50:10 PST 2023


https://github.com/mjklemm updated https://github.com/llvm/llvm-project/pull/73124

>From ba38aec7ac04c63fd5167908fe7f91d6ac7bceed Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Wed, 22 Nov 2023 14:22:20 +0100
Subject: [PATCH 1/5] Let the linker fail on multiple definitions of main()

---
 clang/lib/Driver/ToolChains/CommonArgs.cpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 5d2cd1959b06925..30c249d05677ce5 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1018,7 +1018,20 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
       break;
     }
   } else {
+    // --whole-archive needs to be part of the link line to make sure
+    // that the main() function from Fortran_main.a is pulled in by
+    // the linker.
+    //
+    // We are using this --whole-archive/--no-whole-archive bracket w/o
+    // any further checks, because -Wl,--whole-archive at the flang-new new
+    // line will not sucessfully complete, unless the user correctly specified
+    // -Wl,--no-whole-archive (e.g., -Wl,--whole-archive -ldummy
+    // -Wl,--no-whole-archive).
+    CmdArgs.push_back("--whole-archive");
     CmdArgs.push_back("-lFortran_main");
+    CmdArgs.push_back("--no-whole-archive");
+
+    // Perform regular linkage of the remaining runtime libraries.
     CmdArgs.push_back("-lFortranRuntime");
     CmdArgs.push_back("-lFortranDecimal");
   }
@@ -1029,7 +1042,7 @@ void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
                                          ArgStringList &CmdArgs) {
   // Default to the <driver-path>/../lib directory. This works fine on the
   // platforms that we have tested so far. We will probably have to re-fine
-  // this in the future. In particular, on some platforms, we may need to use
+  // this in the future. In particular, on some platforms, we may need to useq
   // lib64 instead of lib.
   SmallString<256> DefaultLibPath =
       llvm::sys::path::parent_path(TC.getDriver().Dir);

>From 7d1180b11ed02cedf1c9fea56bf2ff329274c066 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Wed, 22 Nov 2023 15:18:51 +0100
Subject: [PATCH 2/5] Improve comments and remove accidental typo

---
 clang/lib/Driver/ToolChains/CommonArgs.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 30c249d05677ce5..12e3ce184898250 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1023,10 +1023,10 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
     // the linker.
     //
     // We are using this --whole-archive/--no-whole-archive bracket w/o
-    // any further checks, because -Wl,--whole-archive at the flang-new new
-    // line will not sucessfully complete, unless the user correctly specified
-    // -Wl,--no-whole-archive (e.g., -Wl,--whole-archive -ldummy
-    // -Wl,--no-whole-archive).
+    // any further checks, because -Wl,--whole-archive at the flang
+    // driver's link line will not sucessfully complete, unless the user
+    // correctly specified -Wl,--whole-archive/-Wl,--no-whole-archive
+    // (e.g., -Wl,--whole-archive -ldummy -Wl,--no-whole-archive).
     CmdArgs.push_back("--whole-archive");
     CmdArgs.push_back("-lFortran_main");
     CmdArgs.push_back("--no-whole-archive");
@@ -1042,7 +1042,7 @@ void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
                                          ArgStringList &CmdArgs) {
   // Default to the <driver-path>/../lib directory. This works fine on the
   // platforms that we have tested so far. We will probably have to re-fine
-  // this in the future. In particular, on some platforms, we may need to useq
+  // this in the future. In particular, on some platforms, we may need to use
   // lib64 instead of lib.
   SmallString<256> DefaultLibPath =
       llvm::sys::path::parent_path(TC.getDriver().Dir);

>From 30dab7ebddf1de4836fc3d532fc33b4a7e58837d Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Wed, 22 Nov 2023 20:26:02 +0100
Subject: [PATCH 3/5] Correct link line test for flang-new (for Linux)

---
 flang/test/Driver/linker-flags.f90 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/test/Driver/linker-flags.f90 b/flang/test/Driver/linker-flags.f90
index a1417057d4da068..55b13952db43c17 100644
--- a/flang/test/Driver/linker-flags.f90
+++ b/flang/test/Driver/linker-flags.f90
@@ -31,7 +31,7 @@
 !       executable and may find the GNU linker from MinGW or Cygwin.
 ! UNIX-LABEL:  "{{.*}}ld{{(\.exe)?}}"
 ! UNIX-SAME: "[[object_file]]"
-! UNIX-SAME: "-lFortran_main" "-lFortranRuntime" "-lFortranDecimal" "-lm"
+! UNIX-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal" "-lm"
 
 ! DARWIN-LABEL:  "{{.*}}ld{{(\.exe)?}}"
 ! DARWIN-SAME: "[[object_file]]"
@@ -41,7 +41,7 @@
 
 ! HAIKU-LABEL:  "{{.*}}ld{{(\.exe)?}}"
 ! HAIKU-SAME: "[[object_file]]"
-! HAIKU-SAME: "-lFortran_main" "-lFortranRuntime" "-lFortranDecimal"
+! HAIKU-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal"
 
 ! MINGW-LABEL:  "{{.*}}ld{{(\.exe)?}}"
 ! MINGW-SAME: "[[object_file]]"

>From 72f56d7f03343b9c183b929a4226de89f92472b4 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 23 Nov 2023 14:26:18 +0100
Subject: [PATCH 4/5] Extend flang test system with %clang substitution

---
 flang/test/lit.cfg.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index dda8ed456c986a5..f227dab11c83120 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -122,6 +122,7 @@
 # the build directory holding that tool.
 tools = [
     ToolSubst("%flang", command=FindTool("flang-new"), unresolved="fatal"),
+    ToolSubst("%clang", command=FindTool("clang"), unresolved="fatal"),
     ToolSubst(
         "%flang_fc1",
         command=FindTool("flang-new"),

>From f204dcb1c7f7099f1f0f687621dfea4f3b61cdeb Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 23 Nov 2023 12:25:13 +0100
Subject: [PATCH 5/5] Add tests for failing linker (albeit not very
 sophisticated yet)

---
 flang/test/Driver/main_dupes.f90        | 13 +++++++++++++
 flang/test/Driver/main_dupes.f90.c-part |  8 ++++++++
 2 files changed, 21 insertions(+)
 create mode 100644 flang/test/Driver/main_dupes.f90
 create mode 100644 flang/test/Driver/main_dupes.f90.c-part

diff --git a/flang/test/Driver/main_dupes.f90 b/flang/test/Driver/main_dupes.f90
new file mode 100644
index 000000000000000..7ed5128ca5dd32f
--- /dev/null
+++ b/flang/test/Driver/main_dupes.f90
@@ -0,0 +1,13 @@
+! RUN: %clang -x c -o %t.c-part -c %s.c-part
+! RUN: %flang -o %t -c %s
+! RUN: not %flang -o %t.exe %t %t.c-part 2>&1
+
+! TODO: potentially add further checks to ensure that proper
+!       linker error messages are detected and checked via
+!       FileCheck.
+
+program main_dupes
+    ! Irrelevant what to do in here.
+    ! Test is supposed to fail at link time.
+    print '(A)', 'Hello from Fortran'
+end program main_dupes
diff --git a/flang/test/Driver/main_dupes.f90.c-part b/flang/test/Driver/main_dupes.f90.c-part
new file mode 100644
index 000000000000000..baae10f94e26364
--- /dev/null
+++ b/flang/test/Driver/main_dupes.f90.c-part
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main(int argc, char * argv[]) {
+    // Irrelevant what to do in here.
+    // Test is supposed to fail at link time.
+    printf("Hello from C [%s]\n", __FUNCTION__);
+    return 0;
+}



More information about the cfe-commits mailing list