]> granicus.if.org Git - clang/commitdiff
MarkEOLs should only be true for clang-cl.exe.
authorStephen Hines <srhines@google.com>
Wed, 20 Apr 2016 00:33:06 +0000 (00:33 +0000)
committerStephen Hines <srhines@google.com>
Wed, 20 Apr 2016 00:33:06 +0000 (00:33 +0000)
Summary:
https://llvm.org/bugs/show_bug.cgi?id=27396

This fixes an issue in response files where "\r\n" was being interpreted
as two EOL markers (i.e. we consumed the '\r' as terminating the
previous token, and then parsed the '\n' as a significant EOL). This
breaks response files where joined arguments get split across multiple
lines (like "-x\r\nc"). I also fixed an accidental issue in the
response-file.c test, where the response file is appended to, instead of
being overwritten.

Reviewers: rnk

Subscribers: danalbert, llvm-commits

Differential Revision: http://reviews.llvm.org/D19289

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@266840 91177308-0d34-0410-b5e6-96231b3b80d8

test/Driver/response-file-extra-whitespace.c [new file with mode: 0644]
test/Driver/response-file.c
tools/driver/driver.cpp

diff --git a/test/Driver/response-file-extra-whitespace.c b/test/Driver/response-file-extra-whitespace.c
new file mode 100644 (file)
index 0000000..93b32bb
--- /dev/null
@@ -0,0 +1,12 @@
+// Check that clang is able to process response files with extra whitespace.
+// We generate a dos-style file with \r\n for line endings, and then split
+// some joined arguments (like "-x c") across lines to ensure that regular
+// clang (not clang-cl) can process it correctly.
+//
+// RUN: echo -en "-x\r\nc\r\n-DTEST\r\n" > %t.0.txt
+// RUN: %clang -E @%t.0.txt %s -v 2>&1 | FileCheck %s -check-prefix=SHORT
+// SHORT: extern int it_works;
+
+#ifdef TEST
+extern int it_works;
+#endif
index 208a941e8723bb7a7fc29e8252073508254c5fd5..bd336309adf8e611271a2699cdaeb410fd907d64 100644 (file)
@@ -4,7 +4,7 @@
 // Since this is a short response file, clang must not use a response file
 // to pass its parameters to other tools. This is only necessary for a large
 // number of parameters.
-// RUN: echo "-DTEST" >> %t.0.txt
+// RUN: echo "-DTEST" > %t.0.txt
 // RUN: %clang -E @%t.0.txt %s -v 2>&1 | FileCheck %s -check-prefix=SHORT
 // SHORT-NOT: Arguments passed via response file
 // SHORT: extern int it_works;
index bd3c533904a55b590b3fb6409655606d71fc51b9..b7097e3faf1960a7c839ed6b7d015aa41536dff1 100644 (file)
@@ -338,18 +338,26 @@ int main(int argc_, const char **argv_) {
   // have to manually search for a --driver-mode=cl argument the hard way.
   // Finally, our -cc1 tools don't care which tokenization mode we use because
   // response files written by clang will tokenize the same way in either mode.
-  llvm::cl::TokenizerCallback Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
+  bool ClangCLMode = false;
   if (TargetAndMode.second == "--driver-mode=cl" ||
       std::find_if(argv.begin(), argv.end(), [](const char *F) {
         return F && strcmp(F, "--driver-mode=cl") == 0;
       }) != argv.end()) {
-    Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
+    ClangCLMode = true;
   }
 
   // Determines whether we want nullptr markers in argv to indicate response
-  // files end-of-lines. We only use this for the /LINK driver argument.
-  bool MarkEOLs = true;
-  if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
+  // files end-of-lines. We only use this for the /LINK driver argument with
+  // clang-cl.exe on Windows.
+  bool MarkEOLs = false;
+
+  llvm::cl::TokenizerCallback Tokenizer = &llvm::cl::TokenizeGNUCommandLine;
+  if (ClangCLMode) {
+    Tokenizer = &llvm::cl::TokenizeWindowsCommandLine;
+    MarkEOLs = true;
+  }
+
+  if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))
     MarkEOLs = false;
   llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs);