[lit] Fix the return code for "not not" after evaluating "not" internally
authorMartin Storsjö <martin@martin.st>
Sun, 18 Apr 2021 21:37:13 +0000 (00:37 +0300)
committerMartin Storsjö <martin@martin.st>
Sun, 18 Apr 2021 21:37:13 +0000 (00:37 +0300)
This fixes cases where "not not <command>" is supposed to return
only the error codes 0 or 1, but after efee57925c3f46c74c6697,
it passed the original error code through.

This was visible on AIX in the shtest-output-printing.py testcase,
where 'wc' returns 2, while it returns 1 on other platforms, and the
test required "not not" to normalize it to 1.

llvm/utils/lit/lit/TestRunner.py
llvm/utils/lit/tests/Inputs/shtest-not/fail2.py [new file with mode: 0644]
llvm/utils/lit/tests/Inputs/shtest-not/not-calls-fail2.txt [new file with mode: 0644]
llvm/utils/lit/tests/shtest-not.py

index cb4102e..dea2816 100644 (file)
@@ -614,7 +614,7 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
     assert isinstance(cmd, ShUtil.Pipeline)
 
     procs = []
-    negate_procs = []
+    proc_not_counts = []
     default_stdin = subprocess.PIPE
     stderrTempFiles = []
     opened_files = []
@@ -784,7 +784,7 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
                                           stderr = stderr,
                                           env = cmd_shenv.env,
                                           close_fds = kUseCloseFDs))
-            negate_procs.append((not_count % 2) != 0)
+            proc_not_counts.append(not_count)
             # Let the helper know about this process
             timeoutHelper.addProcess(procs[-1])
         except OSError as e:
@@ -837,8 +837,10 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
         # Detect Ctrl-C in subprocess.
         if res == -signal.SIGINT:
             raise KeyboardInterrupt
-        if negate_procs[i]:
+        if proc_not_counts[i] % 2:
             res = not res
+        elif proc_not_counts[i] > 1:
+            res = 1 if res != 0 else 0
 
         # Ensure the resulting output is always of string type.
         try:
diff --git a/llvm/utils/lit/tests/Inputs/shtest-not/fail2.py b/llvm/utils/lit/tests/Inputs/shtest-not/fail2.py
new file mode 100644 (file)
index 0000000..e9fb0bc
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+import print_environment
+import sys
+
+print_environment.execute()
+sys.exit(2)
diff --git a/llvm/utils/lit/tests/Inputs/shtest-not/not-calls-fail2.txt b/llvm/utils/lit/tests/Inputs/shtest-not/not-calls-fail2.txt
new file mode 100644 (file)
index 0000000..e184efc
--- /dev/null
@@ -0,0 +1,4 @@
+# Check that "not not" either returns 0 or 1, even if the original
+# program exited with a different code.
+
+# RUN: not not %{python} fail2.py
index 2c9a2d4..2b8a69a 100644 (file)
@@ -10,7 +10,7 @@
 
 # Make sure not and env commands are included in printed commands.
 
-# CHECK: -- Testing: 16 tests{{.*}}
+# CHECK: -- Testing: 17 tests{{.*}}
 
 # CHECK: FAIL: shtest-not :: exclamation-args-nested-none.txt {{.*}}
 # CHECK: $ "!" "!" "!"
 # CHECK: $ "not" "not" "--crash" "env" "-u" "BAR" "not" "env" "-u" "FOO" "BAR=1" "{{[^"]*}}" "pass.py"
 
 
+# CHECK: FAIL: shtest-not :: not-calls-fail2.txt {{.*}}
+# CHECK-NEXT: {{.*}} TEST 'shtest-not :: not-calls-fail2.txt' FAILED {{.*}}
+# CHECK-NEXT: Script:
+# CHECK-NEXT: --
+# CHECK:      --
+# CHECK-NEXT: Exit Code: 1
+
 # CHECK: FAIL: shtest-not :: not-calls-mkdir.txt {{.*}}
 # CHECK: $ "not" "mkdir" {{.*}}
 # CHECK: $ "not" "--crash" "mkdir" "foobar"
 # CHECK: error: command failed with exit status: {{.*}}
 
 # CHECK: Passed:  1
-# CHECK: Failed: 15
+# CHECK: Failed: 16
 # CHECK-NOT: {{.}}