[LLD][COFF] Improve checkFailIfMismatch()
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>
Fri, 29 Mar 2019 19:58:58 +0000 (19:58 +0000)
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>
Fri, 29 Mar 2019 19:58:58 +0000 (19:58 +0000)
As suggested by ruiu here (https://reviews.llvm.org/D58910#1425484), defer a call to toString(File) until it's really needed (if there's an error)

Differential Revision: https://reviews.llvm.org/D59411

llvm-svn: 357305

lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Driver.h
lld/COFF/DriverUtils.cpp

index 99b3b9e..b13ef3a 100644 (file)
@@ -28,6 +28,7 @@ class DefinedAbsolute;
 class DefinedRelative;
 class StringChunk;
 class Symbol;
+class InputFile;
 
 // Short aliases.
 static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
@@ -166,7 +167,7 @@ struct Configuration {
   std::map<std::string, int> AlignComm;
 
   // Used for /failifmismatch.
-  std::map<StringRef, std::pair<StringRef, std::string>> MustMatch;
+  std::map<StringRef, std::pair<StringRef, InputFile *>> MustMatch;
 
   // Used for /alternatename.
   std::map<StringRef, StringRef> AlternateNames;
index f01cf99..bbebe5d 100644 (file)
@@ -314,7 +314,7 @@ void LinkerDriver::parseDirectives(InputFile *File) {
       Config->Entry = addUndefined(mangle(Arg->getValue()));
       break;
     case OPT_failifmismatch:
-      checkFailIfMismatch(Arg->getValue(), toString(File));
+      checkFailIfMismatch(Arg->getValue(), File);
       break;
     case OPT_incl:
       addUndefined(Arg->getValue());
@@ -1283,7 +1283,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
 
   // Handle /failifmismatch
   for (auto *Arg : Args.filtered(OPT_failifmismatch))
-    checkFailIfMismatch(Arg->getValue(), "cmd-line");
+    checkFailIfMismatch(Arg->getValue(), nullptr);
 
   // Handle /merge
   for (auto *Arg : Args.filtered(OPT_merge))
index 1b3ca48..4ad473b 100644 (file)
@@ -180,7 +180,7 @@ void assignExportOrdinals();
 // if value matches previous values for the key.
 // This feature used in the directive section to reject
 // incompatible objects.
-void checkFailIfMismatch(StringRef Arg, StringRef Source);
+void checkFailIfMismatch(StringRef Arg, InputFile *Source);
 
 // Convert Windows resource files (.res files) to a .obj file.
 MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs);
index 6f3cf85..a2f1008 100644 (file)
@@ -698,16 +698,19 @@ void assignExportOrdinals() {
 
 // Parses a string in the form of "key=value" and check
 // if value matches previous values for the same key.
-void checkFailIfMismatch(StringRef Arg, StringRef Source) {
+void checkFailIfMismatch(StringRef Arg, InputFile *Source) {
   StringRef K, V;
   std::tie(K, V) = Arg.split('=');
   if (K.empty() || V.empty())
     fatal("/failifmismatch: invalid argument: " + Arg);
-  std::pair<StringRef, StringRef> Existing = Config->MustMatch[K];
+  std::pair<StringRef, InputFile *> Existing = Config->MustMatch[K];
   if (!Existing.first.empty() && V != Existing.first) {
+    std::string SourceStr = Source ? toString(Source) : "cmd-line";
+    std::string ExistingStr =
+        Existing.second ? toString(Existing.second) : "cmd-line";
     fatal("/failifmismatch: mismatch detected for '" + K + "':\n>>> " +
-          Existing.second + " has value " + Existing.first + "\n>>> " +
-          Source + " has value " + V);
+          ExistingStr + " has value " + Existing.first + "\n>>> " + SourceStr +
+          " has value " + V);
   }
   Config->MustMatch[K] = {V, Source};
 }