r317860 - [Driver] Make clang/cc conforms to UNIX standard

Steven Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 9 17:32:47 PST 2017


Author: steven_wu
Date: Thu Nov  9 17:32:47 2017
New Revision: 317860

URL: http://llvm.org/viewvc/llvm-project?rev=317860&view=rev
Log:
[Driver] Make clang/cc conforms to UNIX standard

Summary:
This is basically reverting r261774 with a tweak for clang-cl. UNIX
standard states:
When c99 encounters a compilation error that causes an object file not
to be created, it shall write a diagnostic to standard error and
continue to compile other source code operands, but it shall not perform
the link phase and it shall return a non-zero exit status

The same goes for c89 or cc. And they are all alias or shims pointing to
clang on Darwin.

The original commit was intended for CUDA so the error message doesn't
get emit twice for both host and device. It seems that the clang driver
has been changed to model the CUDA dependency differently. Now the
driver behaves the same without this commit.

rdar://problem/32223263

Reviewers: thakis, dexonsmith, tra

Reviewed By: tra

Subscribers: jlebar, cfe-commits

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

Added:
    cfe/trunk/test/Driver/cuda-bail-out.cu
    cfe/trunk/test/Driver/unix-conformance.c
Modified:
    cfe/trunk/lib/Driver/Compilation.cpp
    cfe/trunk/test/Driver/output-file-cleanup.c

Modified: cfe/trunk/lib/Driver/Compilation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Compilation.cpp?rev=317860&r1=317859&r2=317860&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Compilation.cpp (original)
+++ cfe/trunk/lib/Driver/Compilation.cpp Thu Nov  9 17:32:47 2017
@@ -182,16 +182,51 @@ int Compilation::ExecuteCommand(const Co
   return ExecutionFailed ? 1 : Res;
 }
 
-void Compilation::ExecuteJobs(
-    const JobList &Jobs,
-    SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const {
+using FailingCommandList = SmallVectorImpl<std::pair<int, const Command *>>;
+
+static bool ActionFailed(const Action *A,
+                         const FailingCommandList &FailingCommands) {
+
+  if (FailingCommands.empty())
+    return false;
+
+  // CUDA can have the same input source code compiled multiple times so do not
+  // compiled again if there are already failures. It is OK to abort the CUDA
+  // pipeline on errors.
+  if (A->isOffloading(Action::OFK_Cuda))
+    return true;
+
+  for (const auto &CI : FailingCommands)
+    if (A == &(CI.second->getSource()))
+      return true;
+
+  for (const Action *AI : A->inputs())
+    if (ActionFailed(AI, FailingCommands))
+      return true;
+
+  return false;
+}
+
+static bool InputsOk(const Command &C,
+                     const FailingCommandList &FailingCommands) {
+  return !ActionFailed(&C.getSource(), FailingCommands);
+}
+
+void Compilation::ExecuteJobs(const JobList &Jobs,
+                              FailingCommandList &FailingCommands) const {
+  // According to UNIX standard, driver need to continue compiling all the
+  // inputs on the command line even one of them failed.
+  // In all but CLMode, execute all the jobs unless the necessary inputs for the
+  // job is missing due to previous failures.
   for (const auto &Job : Jobs) {
+    if (!InputsOk(Job, FailingCommands))
+      continue;
     const Command *FailingCommand = nullptr;
     if (int Res = ExecuteCommand(Job, FailingCommand)) {
       FailingCommands.push_back(std::make_pair(Res, FailingCommand));
-      // Bail as soon as one command fails, so we don't output duplicate error
-      // messages if we die on e.g. the same file.
-      return;
+      // Bail as soon as one command fails in cl driver mode.
+      if (TheDriver.IsCLMode())
+        return;
     }
   }
 }

Added: cfe/trunk/test/Driver/cuda-bail-out.cu
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cuda-bail-out.cu?rev=317860&view=auto
==============================================================================
--- cfe/trunk/test/Driver/cuda-bail-out.cu (added)
+++ cfe/trunk/test/Driver/cuda-bail-out.cu Thu Nov  9 17:32:47 2017
@@ -0,0 +1,54 @@
+// Test clang driver bails out after one error during CUDA compilation.
+
+// REQUIRES: clang-driver
+// REQUIRES: powerpc-registered-target
+// REQUIRES: nvptx-registered-target
+
+#ifdef FORCE_ERROR
+#error compilation failed
+#endif
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DFORCE_ERROR %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DFORCE_ERROR --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DFORCE_ERROR --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   --cuda-device-only %s 2>&1 | FileCheck %s
+
+#if defined(ERROR_HOST) && !defined(__CUDA_ARCH__)
+#error compilation failed
+#endif
+
+#if defined(ERROR_SM35) && (__CUDA_ARCH__ == 350)
+#error compilation failed
+#endif
+
+#if defined(ERROR_SM60) && (__CUDA_ARCH__ == 600)
+#error compilation failed
+#endif
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_HOST --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_SM35 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   --cuda-device-only %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_SM60 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   --cuda-device-only %s 2>&1 | FileCheck %s
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_HOST -DERROR_SM35 --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_HOST -DERROR_SM60 --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_SM35 -DERROR_SM60 --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+
+
+// CHECK: error: compilation failed
+// CHECK-NOT: error: compilation failed

Modified: cfe/trunk/test/Driver/output-file-cleanup.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/output-file-cleanup.c?rev=317860&r1=317859&r2=317860&view=diff
==============================================================================
--- cfe/trunk/test/Driver/output-file-cleanup.c (original)
+++ cfe/trunk/test/Driver/output-file-cleanup.c Thu Nov  9 17:32:47 2017
@@ -41,18 +41,3 @@ invalid C code
 // RUN: not %clang -S %t-dir/1.c %t-dir/2.c
 // RUN: test -f %t-dir/1.s
 // RUN: test ! -f %t-dir/2.s
-
-// When given multiple .c files to compile, clang compiles them in order until
-// it hits an error, at which point it stops.
-//
-// RUN: touch %t-dir/1.c
-// RUN: echo "invalid C code" > %t-dir/2.c
-// RUN: touch %t-dir/3.c
-// RUN: echo "invalid C code" > %t-dir/4.c
-// RUN: touch %t-dir/5.c
-// RUN: not %clang -S %t-dir/1.c %t-dir/2.c %t-dir/3.c %t-dir/4.c %t-dir/5.c
-// RUN: test -f %t-dir/1.s
-// RUN: test ! -f %t-dir/2.s
-// RUN: test ! -f %t-dir/3.s
-// RUN: test ! -f %t-dir/4.s
-// RUN: test ! -f %t-dir/5.s

Added: cfe/trunk/test/Driver/unix-conformance.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/unix-conformance.c?rev=317860&view=auto
==============================================================================
--- cfe/trunk/test/Driver/unix-conformance.c (added)
+++ cfe/trunk/test/Driver/unix-conformance.c Thu Nov  9 17:32:47 2017
@@ -0,0 +1,24 @@
+// Check UNIX conformance for cc/c89/c99
+// When c99 encounters a compilation error that causes an object file not to be
+// created, it shall write a diagnostic to standard error and continue to
+// compile other source code operands, but it shall not perform the link phase
+// and it shall return a non-zero exit status.
+
+// When given multiple .c files to compile, clang compiles them in order until
+// it hits an error, at which point it stops.
+//
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
+//
+// RUN: touch %t-dir/1.c
+// RUN: echo "invalid C code" > %t-dir/2.c
+// RUN: touch %t-dir/3.c
+// RUN: echo "invalid C code" > %t-dir/4.c
+// RUN: touch %t-dir/5.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c %t-dir/3.c %t-dir/4.c %t-dir/5.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
+// RUN: test -f %t-dir/3.s
+// RUN: test ! -f %t-dir/4.s
+// RUN: test -f %t-dir/5.s




More information about the cfe-commits mailing list