[lld] r187095 - [PECOFF] Add /failifmismatch option.

Rui Ueyama ruiu at google.com
Wed Jul 24 18:23:50 PDT 2013


Author: ruiu
Date: Wed Jul 24 20:23:50 2013
New Revision: 187095

URL: http://llvm.org/viewvc/llvm-project?rev=187095&view=rev
Log:
[PECOFF] Add /failifmismatch option.

Modified:
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkOptions.td
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=187095&r1=187094&r2=187095&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Wed Jul 24 20:23:50 2013
@@ -15,6 +15,7 @@
 
 #include <cstdlib>
 #include <sstream>
+#include <map>
 
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -215,6 +216,26 @@ std::vector<StringRef> splitPathList(Str
   return std::move(ret);
 }
 
+// Handle /failifmatch option.
+bool handleFailIfMismatchOption(StringRef option,
+                                std::map<StringRef, StringRef> &mustMatch,
+                                raw_ostream &diagnostics) {
+  StringRef key, value;
+  llvm::tie(key, value) = option.split('=');
+  if (key.empty() || value.empty()) {
+    diagnostics << "error: malformed /failifmatch option: " << option << "\n";
+    return false;
+  }
+  auto it = mustMatch.find(key);
+  if (it != mustMatch.end() && it->second != value) {
+    diagnostics << "error: mismatch detected: '" << it->second << "' and '"
+                << value << "' for key '" << key << "'\n";
+    return false;
+  }
+  mustMatch[key] = value;
+  return true;
+}
+
 // Process "LINK" environment variable. If defined, the value of the variable
 // should be processed as command line arguments.
 std::vector<const char *> processLinkEnv(PECOFFTargetInfo &info,
@@ -367,6 +388,23 @@ bool WinLinkDriver::parse(int argc, cons
     defaultLibs.push_back((*it)->getValue());
   }
 
+  // Handle /failifmismatch. /failifmismatch is the hidden linker option behind
+  // the scenes of "detect_mismatch" pragma. If the compiler finds "#pragma
+  // detect_mismatch(name, value)", it outputs "/failifmismatch:name=value" to
+  // the .drectve section of the resultant object file. The linker raises an
+  // error if conflicting /failmismatch options are given. Conflicting options
+  // are the options with the same key but with different values.
+  //
+  // This feature is used to prevent inconsistent object files from linking.
+  std::map<StringRef, StringRef> mustMatch;
+  for (llvm::opt::arg_iterator
+           it = parsedArgs->filtered_begin(OPT_failifmismatch),
+           ie = parsedArgs->filtered_end();
+       it != ie; ++it) {
+    if (!handleFailIfMismatchOption((*it)->getValue(), mustMatch, diagnostics))
+      return true;
+  }
+
   // Add input files
   std::vector<StringRef> inputPaths;
   for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_INPUT),

Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=187095&r1=187094&r2=187095&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Wed Jul 24 20:23:50 2013
@@ -59,5 +59,9 @@ def incl : _Separate<"include">,
     HelpText<"Force symbol to be added to symbol table as undefined one">;
 def incl_c : _Joined<"include:", incl>;
 
+// No help text because /failifmismatch is not intended to be used by the user.
+def failifmismatch : _Separate<"failifmismatch">;
+def failifmismatch_c : _Joined<"failifmismatch:", failifmismatch>;
+
 def help : _Flag<"help">;
 def help_q : _Flag<"?">, Alias<help>;

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=187095&r1=187094&r2=187095&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Wed Jul 24 20:23:50 2013
@@ -187,4 +187,15 @@ TEST_F(WinLinkParserTest, NoInputFiles)
   EXPECT_EQ("No input files\n", errorMessage());
 }
 
+TEST_F(WinLinkParserTest, FailIfMismatch_Match) {
+  EXPECT_FALSE(parse("link.exe", "/failifmismatch:foo=bar",
+                     "/failifmismatch:foo=bar", "/failifmismatch:abc=def",
+                     "a.out", nullptr));
+}
+
+TEST_F(WinLinkParserTest, FailIfMismatch_Mismatch) {
+  EXPECT_TRUE(parse("link.exe", "/failifmismatch:foo=bar",
+                    "/failifmismatch:foo=baz", "a.out", nullptr));
+}
+
 } // end anonymous namespace





More information about the llvm-commits mailing list