diff --git a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py --- a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py +++ b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py @@ -196,6 +196,7 @@ #include int main(int, char**) { std::printf("MACRO=%u\\n", MACRO); + return 0; } """ compileFlagsIndex = findIndex(self.config.substitutions, lambda x: x[0] == '%{compile_flags}') @@ -209,6 +210,19 @@ output2 = dsl.programOutput(self.config, source) self.assertEqual(output2, "MACRO=2\n") + def test_program_stderr_is_not_conflated_with_stdout(self): + # Run a program that produces stdout output and stderr output too, making + # sure the stderr output does not pollute the stdout output. + source = """ + #include + int main(int, char**) { + std::fprintf(stdout, "STDOUT-OUTPUT"); + std::fprintf(stderr, "STDERR-OUTPUT"); + return 0; + } + """ + self.assertEqual(dsl.programOutput(self.config, source), "STDOUT-OUTPUT") + class TestHasLocale(SetupConfigs): """ diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py --- a/libcxx/utils/libcxx/test/dsl.py +++ b/libcxx/utils/libcxx/test/dsl.py @@ -64,9 +64,20 @@ if not os.path.exists(d): os.makedirs(d) res = lit.TestRunner.executeScriptInternal(test, litConfig, tmpBase, parsedCommands, execDir) - if isinstance(res, lit.Test.Result): - res = ('', '', 127, None) - return res + if isinstance(res, lit.Test.Result): # Handle failure to parse the Lit test + res = ('', res.output, 127, None) + (out, err, exitCode, timeoutInfo) = res + + # TODO: As a temporary workaround until https://reviews.llvm.org/D81892 lands, manually + # split any stderr output that is included in stdout. It shouldn't be there, but + # the Lit internal shell conflates stderr and stdout. + conflatedErrorOutput = re.search("(# command stderr:.+$)", out, flags=re.DOTALL) + if conflatedErrorOutput: + conflatedErrorOutput = conflatedErrorOutput.group(0) + out = out[:-len(conflatedErrorOutput)] + err += conflatedErrorOutput + + return (out, err, exitCode, timeoutInfo) def _makeConfigTest(config, testPrefix=''): sourceRoot = os.path.join(config.test_exec_root, '__config_src__') @@ -122,7 +133,7 @@ if exitCode != 0: return None - actualOut = re.search("command output:\n(.+)\n$", out, flags=re.DOTALL) + actualOut = re.search("# command output:\n(.+)\n$", out, flags=re.DOTALL) actualOut = actualOut.group(1) if actualOut else "" return actualOut