IWYU: Return error code if user enables error reporting

Previously CMake ignored the return code from iwyu because old versions
of the tool would exit with an error code even when no header include
violations were detected.  The iwyu project has since changed this
behavior, so the tool no longer returns an error code unless the user
enables error reporting via command line arguments.

Behavior seen with iwyu version 0.19

Source file with missing includes:
 - Case 1: iwyu arguments:
   - return code: 0
   - output: <report of all missing includes>
 - Case 2: iwyu arguments: `-Xiwyu --error`
   - return code: 1
   - output: <report of all missing includes>

Source file with no missing includes:
 - Case 1: iwyu arguments:
   - return code: 0
   - output: `(/path/to/file.cc has correct #includes/fwd-decls)`
 - Case 2: iwyu arguments: `-Xiwyu --error`
   - return code: 0
   - output: `(/path/to/file.cc has correct #includes/fwd-decls)`

Teach CMake to return the iwyu return code if the user has invoked the
tool with any of these command line arguments included:
 - `--error[=N]`
 - `--error_always[=N]`

Fixes: #24066
This commit is contained in:
Ashish Sadanandan
2023-03-31 22:41:48 -06:00
committed by Brad King
parent e256e35daa
commit fcacc319d9
8 changed files with 28 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
#include "cmcmd.h"
#include <functional>
#include <iterator>
#include <cm/optional>
#include <cmext/algorithm>
@@ -345,7 +346,6 @@ int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
cm::append(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
// Run the iwyu command line. Capture its stderr and hide its stdout.
// Ignore its return code because the tool always returns non-zero.
std::string stdErr;
int ret;
if (!cmSystemTools::RunSingleCommand(iwyu_cmd, nullptr, &stdErr, &ret,
@@ -359,8 +359,15 @@ int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
<< stdErr << "\n";
}
// always return 0 we don't want to break the compile
return 0;
// Older versions of iwyu always returned a non-zero exit code,
// so ignore it unless the user has enabled errors.
auto has_error_opt = std::find_if(
iwyu_cmd.cbegin(), iwyu_cmd.cend(),
[](std::string const& opt) { return cmHasLiteralPrefix(opt, "--error"); });
bool errors_enabled = has_error_opt != iwyu_cmd.cend() &&
has_error_opt != iwyu_cmd.cbegin() &&
*std::prev(has_error_opt) == "-Xiwyu";
return errors_enabled ? ret : 0;
}
int HandleTidy(const std::string& runCmd, const std::string& sourceFile,

View File

@@ -0,0 +1 @@
[^0]

View File

@@ -0,0 +1,4 @@
Warning: include-what-you-use reported diagnostics:
should add these lines:
*
#include <\.\.\.>

View File

@@ -0,0 +1,3 @@
enable_language(C)
set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -Xiwyu --error)
add_executable(main main.c)

View File

@@ -0,0 +1 @@
[^0]

View File

@@ -0,0 +1,4 @@
Warning: include-what-you-use reported diagnostics:
should add these lines:
*
#include <\.\.\.>

View File

@@ -0,0 +1,3 @@
enable_language(CXX)
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -Xiwyu --error)
add_executable(main main.cxx)

View File

@@ -16,6 +16,8 @@ endfunction()
run_iwyu(C)
run_iwyu(CXX)
run_iwyu(C-error)
run_iwyu(CXX-error)
if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
run_iwyu(C-launch)
run_iwyu(CXX-launch)