[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