Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package include-what-you-use for 
openSUSE:Factory checked in at 2022-04-16 00:15:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/include-what-you-use (Old)
 and      /work/SRC/openSUSE:Factory/.include-what-you-use.new.1941 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "include-what-you-use"

Sat Apr 16 00:15:33 2022 rev:14 rq:970336 version:0.18

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/include-what-you-use/include-what-you-use.changes    
    2021-12-13 20:50:31.972640160 +0100
+++ 
/work/SRC/openSUSE:Factory/.include-what-you-use.new.1941/include-what-you-use.changes
      2022-04-16 00:15:56.577784791 +0200
@@ -1,0 +2,11 @@
+Sun Apr 10 17:15:50 UTC 2022 - Aaron Puchert <aaronpuch...@alice-dsl.net>
+
+- Update to version 0.18, update LLVM/Clang to version 14.
+  * Fix crash on C++20 consteval expressions.
+  * Use more conventional exit codes. (Breaking change!)
+  * Fix deprecation warning for python3.
+  * Fix crash on va_list on AArch64.
+  * Improved support for using-declarations based on new Clang
+    design.
+
+-------------------------------------------------------------------

Old:
----
  include-what-you-use-0.17.src.tar.gz

New:
----
  include-what-you-use-0.18.src.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ include-what-you-use.spec ++++++
--- /var/tmp/diff_new_pack.rUNF3U/_old  2022-04-16 00:15:57.057785432 +0200
+++ /var/tmp/diff_new_pack.rUNF3U/_new  2022-04-16 00:15:57.065785443 +0200
@@ -1,8 +1,8 @@
 #
 # spec file for package include-what-you-use
 #
-# Copyright (c) 2021 SUSE LLC
-# Copyright (c) 2021 Aaron Puchert.
+# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2022 Aaron Puchert.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,8 +17,10 @@
 #
 
 
+%define _llvm_version 14
+
 Name:           include-what-you-use
-Version:        0.17
+Version:        0.18
 Release:        0
 Summary:        A tool to analyze #includes in C and C++ source files
 License:        NCSA
@@ -28,10 +30,10 @@
 Patch1:         fix-shebang.patch
 Patch2:         iwyu_include_picker.patch
 BuildRequires:  c++_compiler
-BuildRequires:  clang13-devel
+BuildRequires:  clang%{_llvm_version}-devel
 BuildRequires:  cmake
 BuildRequires:  libstdc++-devel
-BuildRequires:  llvm13-devel
+BuildRequires:  llvm%{_llvm_version}-devel
 BuildRequires:  python
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 

++++++ include-what-you-use-0.17.src.tar.gz -> 
include-what-you-use-0.18.src.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/.github/workflows/ci.yml 
new/include-what-you-use/.github/workflows/ci.yml
--- old/include-what-you-use/.github/workflows/ci.yml   2021-12-05 
13:58:23.000000000 +0100
+++ new/include-what-you-use/.github/workflows/ci.yml   2022-03-29 
20:31:46.000000000 +0200
@@ -1,8 +1,11 @@
 name: IWYU CI
 
 on:
-  - push
-  - pull_request
+  push:
+  pull_request:
+  schedule:
+    # Run build of master at 03:38 every day
+    - cron: '38 3 * * *'
 
 defaults:
   run:
@@ -15,7 +18,7 @@
       fail-fast: false
 
     env:
-      LLVM_TAG: -13
+      LLVM_TAG: -14
 
     steps:
       - name: Install prerequisites
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/README.md 
new/include-what-you-use/README.md
--- old/include-what-you-use/README.md  2021-12-05 13:58:23.000000000 +0100
+++ new/include-what-you-use/README.md  2022-03-29 20:31:46.000000000 +0200
@@ -108,19 +108,23 @@
 
 The original design was built for Make, but a number of alternative run modes 
have come up over the years.
 
-#### Plugging into Make ####
+#### Running on single source file ####
 
-The easiest way to run IWYU over your codebase is to run
+The simplest way to use IWYU is to run it against a single source file:
 
-      make -k CXX=/path/to/llvm/Debug+Asserts/bin/include-what-you-use
+      include-what-you-use $CXXFLAGS myfile.cc
 
-or
+where `$CXXFLAGS` are the flags you would normally pass to the compiler.
 
-      make -k CXX=/path/to/llvm/Release/bin/include-what-you-use
+#### Plugging into existing build system ####
 
-(include-what-you-use always exits with an error code, so the build system 
knows it didn't build a .o file.  Hence the need for `-k`.)
+Typically there is already a build system containing the relevant compiler 
flags for all source files. Replace your compiler with `include-what-you-use` 
to generate a large batch of IWYU advice. Depending on your build system/build 
tools, this can take many forms, but for a simple GNU Make system it might look 
like this:
 
-Include-what-you-use only analyzes .cc (or .cpp) files built by `make`, along 
with their corresponding .h files.  If your project has a .h file with no 
corresponding .cc file, IWYU will ignore it unless you use the `--check_also` 
switch to add it for analysis together with a .cc file.
+      make -k CXX=include-what-you-use CXXFLAGS="-Xiwyu --error_always"
+
+(The additional `-Xiwyu --error_always` switch makes `include-what-you-use` 
always exit with an error code, so the build system knows it didn't build a .o 
file.  Hence the need for `-k`.)
+
+In this mode `include-what-you-use` only analyzes the .cc (or .cpp) files 
known to your build system, along with their corresponding .h files.  If your 
project has a .h file with no corresponding .cc file, IWYU will ignore it 
unless you use the `--check_also` switch to add it for analysis together with a 
.cc file. It is possible to run IWYU against individual header files, provided 
the compiler flags are carefully constructed to match all includers.
 
 #### Using with CMake ####
 
@@ -170,7 +174,7 @@
 
 We also include a tool that automatically fixes up your source files based on 
the IWYU recommendations.  This is also alpha-quality software!  Here's how to 
use it (requires python):
 
-      make -k CXX=/path/to/llvm/Debug+Asserts/bin/include-what-you-use 2> 
/tmp/iwyu.out
+      make -k CXX=include-what-you-use CXXFLAGS="-Xiwyu --error_always" 2> 
/tmp/iwyu.out
       python fix_includes.py < /tmp/iwyu.out
 
 If you don't like the way `fix_includes.py` munges your `#include` lines, you 
can control its behavior via flags. `fix_includes.py --help` will give a full 
list, but these are some common ones:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/fix_includes.py 
new/include-what-you-use/fix_includes.py
--- old/include-what-you-use/fix_includes.py    2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/fix_includes.py    2022-03-29 20:31:46.000000000 
+0200
@@ -82,9 +82,7 @@
 unless filenames are specified on the commandline, in which case only
 those files are modified.
 
-The exit code is the number of files that were modified (or that would
-be modified if --dry_run was specified) unless that number exceeds 100,
-in which case 100 is returned.
+The exit code is non-zero if a critical error occurs, otherwise zero.
 """
 
 _COMMENT_RE = re.compile(r'\s*//.*')
@@ -2453,11 +2451,12 @@
   if flags.sort_only:
     if not files_to_modify:
       sys.exit('FATAL ERROR: -s flag requires a list of filenames')
-    return SortIncludesInFiles(files_to_modify, flags)
+    SortIncludesInFiles(files_to_modify, flags)
   else:
-    return ProcessIWYUOutput(sys.stdin, files_to_modify, flags, 
cwd=os.getcwd())
+    ProcessIWYUOutput(sys.stdin, files_to_modify, flags, cwd=os.getcwd())
+
+  return 0
 
 
 if __name__ == '__main__':
-  num_files_fixed = main(sys.argv)
-  sys.exit(min(num_files_fixed, 100))
+  sys.exit(main(sys.argv))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/include-what-you-use.1 
new/include-what-you-use/include-what-you-use.1
--- old/include-what-you-use/include-what-you-use.1     2021-12-05 
13:58:23.000000000 +0100
+++ new/include-what-you-use/include-what-you-use.1     2022-03-29 
20:31:46.000000000 +0200
@@ -1,10 +1,10 @@
-.\" t -*- coding: UTF-8 -*-
+.\" t -*- coding: utf-8 -*-
 .\" Man page for include-what-you-use
 .\"
 .\" This file is distributed under the University of Illinois Open Source
 .\" License. See LICENSE.TXT for details.
 .\"
-.TH INCLUDE-WHAT-YOU-USE 1 "2019-11-02" include-what-you-use "User Commands"
+.TH INCLUDE-WHAT-YOU-USE 1 "2022-02-21" include-what-you-use "User Commands"
 .SH NAME
 include-what-you-use \- analyze includes in C and C++ source files.
 .SH SYNOPSIS
@@ -47,6 +47,18 @@
 .B \-\-cxx17ns
 Suggest the more concise syntax for nested namespaces introduced in C++17.
 .TP
+.BI \-\-error [=N]
+Exit with error code
+.IR N
+(defaults to 1 if omitted) if there are \(lqinclude-what-you-use\(rq
+violations.
+.TP
+.BI \-\-error_always [=N]
+Exit with error code
+.IR N
+(defaults to 1 if omitted) whether there are \(lqinclude-what-you-use\(rq
+violations or not (for use with \fBmake(1)\fR).
+.TP
 .BI \-\-keep= glob
 Always keep the includes matched by
 .IR glob .
@@ -113,10 +125,16 @@
 Set verbosity. At the highest level, this will dump the AST of the source file
 and explain all decisions.
 .SH EXIT STATUS
+By default
 .B include-what-you-use
-always returns with a nonzero status code to make usage with
-.BR make (1)
-feasible.
+exits with zero exit code unless there's a critical error, but
+.B \-\-error
+or
+.B \-\-error_always
+can be used to customize the exit code depending on invoker expectations.
+See
+.IR EXAMPLE\fR.
+
 .SH MAPPING FILES
 Sometimes headers are not meant to be included directly,
 and sometimes headers are guaranteed to include other headers.
@@ -240,18 +258,22 @@
 .UE
 on GitHub.
 .SH EXAMPLE
-The easiest way to run
+It is possible to put
 .B include-what-you-use
-over your codebase is to run
+in place of your compiler to process all source files known to your build 
system
 .PP
 .RS
 .EX
-make \-k CC=include-what-you-use CXX=include-what-you-use
+make \-k CC=include-what-you-use CFLAGS="-Xiwyu --error_always"
+.EE
+
+.EX
+make \-k CXX=include-what-you-use CXXFLAGS="-Xiwyu --error_always"
 .EE
 .RE
 .PP
-The program always exits with an error code, so the build system knows that it
-didn't build an object file. Hence the need for
+With \fB-Xiwyu --error_always\fR the program always exits with an error code, 
so
+the build system knows that it didn't build an object file. Hence the need for
 .BR -k .
 It only analyzes source files built by
 .BR make (1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu.cc 
new/include-what-you-use/iwyu.cc
--- old/include-what-you-use/iwyu.cc    2021-12-05 13:58:23.000000000 +0100
+++ new/include-what-you-use/iwyu.cc    2022-03-29 20:31:46.000000000 +0200
@@ -1345,6 +1345,15 @@
     if (decl == nullptr)   // only class-types are candidates for returning 
true
       return false;
 
+    // Sometimes a type points back to an implicit decl (e.g. a bultin type),
+    // and we can't do author-intent analysis without location information.
+    // Assume that it's not forward-declarable.
+    if (decl->isImplicit()) {
+      VERRS(5) << "Skipping forward-declare analysis for implicit decl: '"
+               << PrintableDecl(decl) << "'\n";
+      return false;
+    }
+
     // If we're a template specialization, we also accept
     // forward-declarations of the underlying template (vector<T>, not
     // vector<int>).
@@ -1901,7 +1910,7 @@
     // If this cast requires a user-defined conversion of the from-type, look 
up
     // its return type so we can see through up/down-casts via such 
conversions.
     const Type* converted_from_type = nullptr;
-    if (const NamedDecl* conv_decl = expr->getConversionFunction()) {
+    if (const NamedDecl* conv_decl = GetConversionFunction(expr)) {
       converted_from_type =
           cast<FunctionDecl>(conv_decl)->getReturnType().getTypePtr();
     }
@@ -2383,12 +2392,10 @@
         // that, and is clearly a c++ path, is fine; its exact
         // contents don't matter that much.
         using clang::Optional;
-        using clang::DirectoryLookup;
         using clang::FileEntryRef;
         const FileEntry* use_file = CurrentFileEntry();
-        const DirectoryLookup* curdir = nullptr;
         Optional<FileEntryRef> file = compiler()->getPreprocessor().LookupFile(
-            CurrentLoc(), "new", true, nullptr, use_file, curdir, nullptr,
+            CurrentLoc(), "new", true, nullptr, use_file, nullptr, nullptr,
             nullptr, nullptr, nullptr, nullptr, false);
         if (file) {
           preprocessor_info().FileInfoFor(use_file)->ReportFullSymbolUse(
@@ -3644,14 +3651,8 @@
 
     // Check if any unrecoverable errors have occurred.
     // There is no point in continuing when the AST is in a bad state.
-    //
-    // EXIT_INVALIDARGS is not a great choice for the return status
-    // because a compile error will not have a strong connection to the
-    // command line arguments, but there are only 2 error codes and
-    // this is the least bad choice.
-    // TODO : Readdress when error codes are reworked.
     if (compiler()->getDiagnostics().hasUnrecoverableErrorOccurred())
-      exit(EXIT_INVALIDARGS);
+      exit(EXIT_FAILURE);
 
     const set<const FileEntry*>* const files_to_report_iwyu_violations_for
         = preprocessor_info().files_to_report_iwyu_violations_for();
@@ -3681,8 +3682,16 @@
     num_edits += preprocessor_info().FileInfoFor(main_file)
         ->CalculateAndReportIwyuViolations();
 
-    // We need to force the compile to fail so we can re-run.
-    exit(EXIT_SUCCESS_OFFSET + num_edits);
+    int exit_code = EXIT_SUCCESS;
+    if (GlobalFlags().exit_code_always) {
+      // If we should always fail, use --error_always value.
+      exit_code = GlobalFlags().exit_code_always;
+    } else if (num_edits > 0) {
+      // If there were IWYU violations, use --error value.
+      exit_code = GlobalFlags().exit_code_error;
+    }
+
+    exit(exit_code);
   }
 
   void ParseFunctionTemplates(Sema& sema, TranslationUnitDecl* tu_decl) {
@@ -4043,6 +4052,20 @@
     return Base::VisitTypedefType(type);
   }
 
+  bool VisitUsingType(clang::UsingType* type) {
+    if (CanIgnoreCurrentASTNode())
+      return true;
+
+    // UsingType is similar to TypedefType, so treat it the same.
+    if (CanForwardDeclareType(current_ast_node())) {
+      ReportDeclForwardDeclareUse(CurrentLoc(), type->getFoundDecl());
+    } else {
+      ReportDeclUse(CurrentLoc(), type->getFoundDecl());
+    }
+
+    return Base::VisitUsingType(type);
+  }
+
   // This is a superclass of RecordType and CXXRecordType.
   bool VisitTagType(clang::TagType* type) {
     if (CanIgnoreCurrentASTNode())  return true;
@@ -4191,6 +4214,8 @@
 using include_what_you_use::CreateCompilerInstance;
 
 int main(int argc, char **argv) {
+  llvm::llvm_shutdown_obj scoped_shutdown;
+
   // X86 target is required to parse Microsoft inline assembly, so we hope it's
   // part of all targets. Clang parser will complain otherwise.
   llvm::InitializeAllTargetInfos();
@@ -4198,21 +4223,19 @@
   llvm::InitializeAllAsmParsers();
 
   // The command line should look like
-  //   path/to/iwyu -Xiwyu --verbose=4 [-Xiwyu --other_iwyu_flag]... 
CLANG_FLAGS... foo.cc
+  //   path/to/iwyu -Xiwyu --verbose=4 [-Xiwyu --other_iwyu_flag]... \
+  //       CLANG_FLAGS... foo.cc
   OptionsParser options_parser(argc, argv);
 
   std::unique_ptr<clang::CompilerInstance> compiler(CreateCompilerInstance(
       options_parser.clang_argc(), options_parser.clang_argv()));
-  if (compiler) {
-    // Create and execute the frontend to generate an LLVM bitcode module.
-    std::unique_ptr<clang::ASTFrontendAction> action(new IwyuAction);
-    compiler->ExecuteAction(*action);
+  if (!compiler) {
+    return EXIT_FAILURE;
   }
 
-  llvm::llvm_shutdown();
-
-  // We always return a failure exit code, to indicate we didn't
-  // successfully compile (produce a .o for) the source files we were
-  // given.
-  return 1;
+  // Create and execute the frontend to generate an LLVM bitcode module.
+  std::unique_ptr<clang::ASTFrontendAction> action(new IwyuAction);
+  compiler->ExecuteAction(*action);
+
+  return EXIT_SUCCESS;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_ast_util.cc 
new/include-what-you-use/iwyu_ast_util.cc
--- old/include-what-you-use/iwyu_ast_util.cc   2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_ast_util.cc   2022-03-29 20:31:46.000000000 
+0200
@@ -32,6 +32,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Stmt.h"
@@ -49,11 +50,14 @@
 
 using clang::ASTDumper;
 using clang::BlockPointerType;
+using clang::CastExpr;
+using clang::CXXBindTemporaryExpr;
 using clang::CXXConstructExpr;
 using clang::CXXConstructorDecl;
 using clang::CXXDeleteExpr;
 using clang::CXXDependentScopeMemberExpr;
 using clang::CXXDestructorDecl;
+using clang::CXXMemberCallExpr;
 using clang::CXXMethodDecl;
 using clang::CXXNewExpr;
 using clang::CXXRecordDecl;
@@ -74,12 +78,15 @@
 using clang::Expr;
 using clang::ExprWithCleanups;
 using clang::FileEntry;
+using clang::FullExpr;
 using clang::FullSourceLoc;
 using clang::FunctionDecl;
 using clang::FunctionType;
 using clang::ImplicitCastExpr;
+using clang::IgnoreExprNodes;
 using clang::InjectedClassNameType;
 using clang::LValueReferenceType;
+using clang::MaterializeTemporaryExpr;
 using clang::MemberExpr;
 using clang::MemberPointerType;
 using clang::NamedDecl;
@@ -1475,4 +1482,36 @@
   return explicit_tpl_args;
 }
 
+// This is lifted from CastExpr::getConversionFunction, and naively simplified
+// to work around bugs with consteval conversion functions.
+const NamedDecl* GetConversionFunction(const CastExpr* expr) {
+  const Expr *subexpr = nullptr;
+  for (const CastExpr *e = expr; e; e = dyn_cast<ImplicitCastExpr>(subexpr)) {
+    // Skip through implicit sema nodes.
+    subexpr = IgnoreExprNodes(e->getSubExpr(), [](Expr* expr) {
+      // FullExpr is ConstantExpr + ExprWithCleanups.
+      if (auto* fe = dyn_cast<FullExpr>(expr))
+        return fe->getSubExpr();
+
+      if (auto* mte = dyn_cast<MaterializeTemporaryExpr>(expr))
+        return mte->getSubExpr();
+
+      if (auto* bte = dyn_cast<CXXBindTemporaryExpr>(expr))
+        return bte->getSubExpr();
+
+      return expr;
+    });
+
+    // Now resolve the conversion function depending on cast kind.
+    if (e->getCastKind() == clang::CK_ConstructorConversion)
+      return cast<CXXConstructExpr>(subexpr)->getConstructor();
+
+    if (e->getCastKind() == clang::CK_UserDefinedConversion) {
+      if (auto *MCE = dyn_cast<CXXMemberCallExpr>(subexpr))
+        return MCE->getMethodDecl();
+    }
+  }
+  return nullptr;
+}
+
 }  // namespace include_what_you_use
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_ast_util.h 
new/include-what-you-use/iwyu_ast_util.h
--- old/include-what-you-use/iwyu_ast_util.h    2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_ast_util.h    2022-03-29 20:31:46.000000000 
+0200
@@ -816,6 +816,10 @@
 // such a concept (declrefexpr, memberexpr), and empty list if none is present.
 clang::TemplateArgumentListInfo GetExplicitTplArgs(const clang::Expr* expr);
 
+// Workaround for https://github.com/llvm/llvm-project/issues/53044. Remove 
this
+// wrapper in favor of Expr::getConversionFunction  when that is fixed 
upstream.
+const clang::NamedDecl* GetConversionFunction(const clang::CastExpr* expr);
+
 }  // namespace include_what_you_use
 
 #endif  // INCLUDE_WHAT_YOU_USE_IWYU_AST_UTIL_H_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_globals.cc 
new/include-what-you-use/iwyu_globals.cc
--- old/include-what-you-use/iwyu_globals.cc    2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_globals.cc    2022-03-29 20:31:46.000000000 
+0200
@@ -98,6 +98,9 @@
          "   --quoted_includes_first: when sorting includes, place quoted\n"
          "        ones first.\n"
          "   --cxx17ns: suggests the more concise syntax introduced in C++17\n"
+         "   --error[=N]: exit with N (default: 1) for iwyu violations\n"
+         "   --error_always[=N]: always exit with N (default: 1) (for use\n"
+         "        with 'make -k')\n"
          "\n"
          "In addition to IWYU-specific options you can specify the following\n"
          "options without -Xiwyu prefix:\n"
@@ -118,6 +121,22 @@
                << "\n";
 }
 
+static bool ParseIntegerOptarg(const char* optarg, int* res) {
+  char* endptr = nullptr;
+  long val = strtol(optarg, &endptr, 10);
+  if (!endptr || endptr == optarg)
+    return false;
+
+  if (*endptr != '\0')
+    return false;
+
+  if (val > INT_MAX || val < INT_MIN)
+    return false;
+
+  *res = (int)val;
+  return true;
+}
+
 OptionsParser::OptionsParser(int argc, char** argv) {
   // Separate out iwyu-specific, intercepted, and clang flags.  iwyu-specific
   // flags are "-Xiwyu <iwyu_flag>", intercepted flags are usual clang flags
@@ -168,7 +187,9 @@
       update_comments(false),
       no_fwd_decls(false),
       quoted_includes_first(false),
-      cxx17ns(false) {
+      cxx17ns(false),
+      exit_code_error(EXIT_SUCCESS),
+      exit_code_always(EXIT_SUCCESS) {
   // Always keep Qt .moc includes; its moc compiler does its own IWYU analysis.
   keep.emplace("*.moc");
 }
@@ -189,6 +210,8 @@
     {"no_fwd_decls", no_argument, nullptr, 'f'},
     {"quoted_includes_first", no_argument, nullptr, 'q' },
     {"cxx17ns", no_argument, nullptr, 'C'},
+    {"error", optional_argument, nullptr, 'e'},
+    {"error_always", optional_argument, nullptr, 'a'},
     {nullptr, 0, nullptr, 0}
   };
   static const char shortopts[] = "v:c:m:n";
@@ -212,7 +235,7 @@
           prefix_header_include_policy = CommandlineFlags::kRemove;
         } else {
           PrintHelp("FATAL ERROR: unknown --prefix_header_includes value.");
-          exit(EXIT_INVALIDARGS);
+          exit(EXIT_FAILURE);
         }
         break;
       case 'h': pch_in_code = true; break;
@@ -222,14 +245,33 @@
         break;
       case 'q': quoted_includes_first = true; break;
       case 'C': cxx17ns = true; break;
+      case 'e':
+        if (!optarg) {
+          exit_code_error = EXIT_FAILURE;
+        } else if (!ParseIntegerOptarg(optarg, &exit_code_error)) {
+          PrintHelp("FATAL ERROR: --error argument must be valid integer.");
+          exit(EXIT_FAILURE);
+        }
+        break;
+      case 'a':
+        if (!optarg) {
+          exit_code_always = EXIT_FAILURE;
+        } else if (!ParseIntegerOptarg(optarg, &exit_code_always)) {
+          PrintHelp(
+              "FATAL ERROR: --error_always argument must be valid "
+              "integer.");
+          exit(EXIT_FAILURE);
+        }
+        break;
       case -1: return optind;   // means 'no more input'
       default:
         PrintHelp("FATAL ERROR: unknown flag.");
-        exit(EXIT_INVALIDARGS);
+        exit(EXIT_FAILURE);
         break;
     }
   }
-  return optind;  // unreachable
+
+  CHECK_UNREACHABLE_("All switches should be handled above");
 }
 
 // Though option -v prints version too, it isn't intercepted because it also
@@ -251,7 +293,7 @@
       case -1: return optind;   // means 'no more input'
       default:
         PrintHelp("FATAL ERROR: unknown flag.");
-        exit(EXIT_INVALIDARGS);
+        exit(EXIT_FAILURE);
         break;
     }
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_globals.h 
new/include-what-you-use/iwyu_globals.h
--- old/include-what-you-use/iwyu_globals.h     2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_globals.h     2022-03-29 20:31:46.000000000 
+0200
@@ -24,15 +24,6 @@
 
 namespace include_what_you_use {
 
-// Exit codes.
-// If invalid args are specified in any form, we return 1,
-// otherwise we return 2 + the number of edits suggested.
-// Of course, this means that IWYU always fails (i.e. never returns 0.)
-// This is intentional, so it can be used with make -k without ever being
-// considered up-to-date.
-static const int EXIT_INVALIDARGS = 1;
-static const int EXIT_SUCCESS_OFFSET = 2;
-
 using std::set;
 using std::string;
 using std::vector;
@@ -102,6 +93,8 @@
   bool no_fwd_decls;  // Disable forward declarations.
   bool quoted_includes_first; // Place quoted includes first in sort order.
   bool cxx17ns; // -C: C++17 nested namespace syntax
+  int exit_code_error;   // Exit with this code for iwyu violations.
+  int exit_code_always;  // Always exit with this exit code.
 };
 
 const CommandlineFlags& GlobalFlags();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_preprocessor.cc 
new/include-what-you-use/iwyu_preprocessor.cc
--- old/include-what-you-use/iwyu_preprocessor.cc       2021-12-05 
13:58:23.000000000 +0100
+++ new/include-what-you-use/iwyu_preprocessor.cc       2022-03-29 
20:31:46.000000000 +0200
@@ -624,9 +624,7 @@
   // #undefs and re-defines a macro, but should work fine in practice.)
   if (macro_loc.isValid())
     macros_definition_loc_[GetName(id)] = macro_loc;
-  for (MacroInfo::tokens_iterator it = macro->tokens_begin();
-       it != macro->tokens_end(); ++it) {
-    const Token& token_in_macro = *it;
+  for (const Token& token_in_macro : macro->tokens()) {
     if (token_in_macro.getKind() == clang::tok::identifier &&
         token_in_macro.getIdentifierInfo()->hasMacroDefinition()) {
       macros_called_from_macros_.push_back(token_in_macro);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_test_util.py 
new/include-what-you-use/iwyu_test_util.py
--- old/include-what-you-use/iwyu_test_util.py  2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_test_util.py  2022-03-29 20:31:46.000000000 
+0200
@@ -39,19 +39,22 @@
 # This is the final summary output that iwyu.cc produces when --verbose >= 1
 # The summary for a given source file should appear in that source file,
 # surrounded by '/**** IWYU_SUMMARY' and '***** IWYU_SUMMARY */'.
+# The leading summary line may also have an expected exit-code in parentheses
+# after the summary marker: '/**** IWYU_SUMMARY(10)'.
 _EXPECTED_SUMMARY_START_RE = re.compile(r'/\*+\s*IWYU_SUMMARY')
+_EXPECTED_SUMMARY_EXIT_CODE_RE = re.compile(r'/\*+\s*IWYU_SUMMARY\((\d+)\)')
 _EXPECTED_SUMMARY_END_RE = re.compile(r'\**\s*IWYU_SUMMARY\s*\*+/')
 _ACTUAL_SUMMARY_START_RE = re.compile(r'^(.*?) should add these lines:$')
 _ACTUAL_SUMMARY_END_RE = re.compile(r'^---$')
 _ACTUAL_REMOVAL_LIST_START_RE = re.compile(r'.* should remove these lines:$')
 _NODIFFS_RE = re.compile(r'^\((.*?) has correct #includes/fwd-decls\)$')
 
-# This is an IWYU_ARGS line that specifies launch arguments 
-# for a test in its source file.
-# Example:
+# This is an IWYU_ARGS line that specifies launch arguments for a test in its
+# source file. Example:
 # // IWYU_ARGS: -Xiwyu --mapping_file=... -I .
 _IWYU_TEST_RUN_ARGS_RE = re.compile(r'^//\sIWYU_ARGS:\s(.*)$')
 
+
 def _PortableNext(iterator):
   if hasattr(iterator, 'next'):
     iterator.next()  # Python 2.4-2.6
@@ -128,7 +131,7 @@
   stdout, _ = p.communicate()
   lines = stdout.decode("utf-8").splitlines(True)
   lines = [line.replace(os.linesep, '\n') for line in lines]
-  return lines
+  return p.returncode, lines
 
 
 def _GetMatchingLines(regex, file_names):
@@ -290,6 +293,16 @@
   return expected_summaries
 
 
+def _GetExpectedExitCode(main_file):
+  with open(main_file, 'r') as fh:
+    for line in fh:
+      m = _EXPECTED_SUMMARY_EXIT_CODE_RE.match(line)
+      if m:
+        res = int(m.group(1))
+        return res
+  return None
+
+
 def _GetActualSummaries(output):
   """Returns a map: source file => list of iwyu summary lines."""
 
@@ -443,7 +456,6 @@
   if env_verbose_level:
     verbosity_flags = ['-Xiwyu', '--verbose=' + env_verbose_level]
 
-  # TODO(csilvers): verify that has exit-status 0.
   cmd = '%s %s %s %s %s' % (
     _ShellQuote(_GetIwyuPath()),
     # Require verbose level 3 so that we can verify the individual diagnostics.
@@ -457,10 +469,16 @@
     cc_file)
   if verbose:
     print('>>> Running %s' % cmd)
-  output = _GetCommandOutput(cmd)
+  exit_code, output = _GetCommandOutput(cmd)
   print(''.join(output))
   sys.stdout.flush()      # don't commingle this output with the failure output
 
+  # Verify exit code if requested
+  expected_exit_code = _GetExpectedExitCode(cc_file)
+  if expected_exit_code is not None and exit_code != expected_exit_code:
+    raise AssertionError('Unexpected exit code, wanted %d, was %d' %
+                         (expected_exit_code, exit_code))
+
   expected_diagnostics = _GetMatchingLines(
       _EXPECTED_DIAGNOSTICS_RE, cpp_files_to_check)
   failures = _CompareExpectedAndActualDiagnostics(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_tool.py 
new/include-what-you-use/iwyu_tool.py
--- old/include-what-you-use/iwyu_tool.py       2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_tool.py       2022-03-29 20:31:46.000000000 
+0200
@@ -367,8 +367,7 @@
         for invocation in invocations:
             proc = invocation.start(verbose)
             print(formatter(proc.get_output()))
-            if proc.returncode != 2:
-                exit_code = 1
+            exit_code = max(exit_code, proc.returncode)
         return exit_code
 
     pending = []
@@ -378,8 +377,7 @@
         for proc in complete:
             pending.remove(proc)
             print(formatter(proc.get_output()))
-            if proc.returncode != 2:
-                exit_code = 1
+            exit_code = max(exit_code, proc.returncode)
 
         # Schedule new processes if there's room.
         capacity = jobs - len(pending)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_tool_test.py 
new/include-what-you-use/iwyu_tool_test.py
--- old/include-what-you-use/iwyu_tool_test.py  2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_tool_test.py  2022-03-29 20:31:46.000000000 
+0200
@@ -64,7 +64,11 @@
 class MockIwyuToolMain(object):
     """ Replacement for iwyu_tool.main to capture parsed arguments. """
     def __init__(self):
-        self.argspec = inspect.getargspec(iwyu_tool.main).args
+        if hasattr(inspect, 'getfullargspec'):
+            getargspec = inspect.getfullargspec
+        else:
+            getargspec = inspect.getargspec
+        self.argspec = getargspec(iwyu_tool.main).args
         self.real_iwyu_tool_main = iwyu_tool.main
         iwyu_tool.main = self._mock
         self.call_args = {}
@@ -131,35 +135,48 @@
 
     def test_returncode(self):
         invocation = MockInvocation()
-        invocation.will_returncode(2)
+        invocation.will_returncode(0)
         self.assertEqual(self._execute([invocation]), 0)
         invocation = MockInvocation()
-        invocation.will_returncode(7)
+        invocation.will_returncode(1)
         self.assertEqual(self._execute([invocation]), 1)
+        invocation = MockInvocation()
+        invocation.will_returncode(2)
+        self.assertEqual(self._execute([invocation]), 2)
 
     def test_returncode_asynchronous(self):
         invocations = [MockInvocation() for _ in range(100)]
         for invocation in invocations:
-            invocation.will_returncode(2)
+            invocation.will_returncode(0)
             invocation.will_block(random.random() / 100)
         self.assertEqual(self._execute(invocations, jobs=100), 0)
         invocations = [MockInvocation() for _ in range(100)]
+        for invocation in invocations:
+            invocation.will_returncode(2)
+            invocation.will_block(random.random() / 100)
+        self.assertEqual(self._execute(invocations, jobs=100), 2)
+        invocations = [MockInvocation() for _ in range(100)]
         for n, invocation in enumerate(invocations):
             invocation.will_returncode(6 if n == 0 else 2)
             invocation.will_block(random.random() / 100)
-        self.assertEqual(self._execute(invocations, jobs=100), 1)
+        self.assertEqual(self._execute(invocations, jobs=100), 6)
 
-    def test_order_synchronous(self):
+    def test_returncode_synchronous(self):
         invocations = [MockInvocation() for _ in range(1)]
         for invocation in invocations:
-            invocation.will_returncode(2)
+            invocation.will_returncode(0)
             invocation.will_block(random.random() / 100)
         self.assertEqual(self._execute(invocations, jobs=100), 0)
         invocations = [MockInvocation() for _ in range(1)]
+        for invocation in invocations:
+            invocation.will_returncode(2)
+            invocation.will_block(random.random() / 100)
+        self.assertEqual(self._execute(invocations, jobs=100), 2)
+        invocations = [MockInvocation() for _ in range(1)]
         for n, invocation in enumerate(invocations):
             invocation.will_returncode(6 if n == 0 else 2)
             invocation.will_block(random.random() / 100)
-        self.assertEqual(self._execute(invocations, jobs=100), 1)
+        self.assertEqual(self._execute(invocations, jobs=100), 6)
 
     @unittest.skipIf(sys.platform.startswith('win'), "POSIX only")
     def test_is_subpath_of_posix(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/iwyu_version.h 
new/include-what-you-use/iwyu_version.h
--- old/include-what-you-use/iwyu_version.h     2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/iwyu_version.h     2022-03-29 20:31:46.000000000 
+0200
@@ -10,6 +10,6 @@
 #ifndef INCLUDE_WHAT_YOU_USE_IWYU_VERSION_H_
 #define INCLUDE_WHAT_YOU_USE_IWYU_VERSION_H_
 
-#define IWYU_VERSION_STRING "0.17"
+#define IWYU_VERSION_STRING "0.18"
 
 #endif  // INCLUDE_WHAT_YOU_USE_IWYU_VERSION_H_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/run_iwyu_tests.py 
new/include-what-you-use/run_iwyu_tests.py
--- old/include-what-you-use/run_iwyu_tests.py  2021-12-05 13:58:23.000000000 
+0100
+++ new/include-what-you-use/run_iwyu_tests.py  2022-03-29 20:31:46.000000000 
+0200
@@ -132,6 +132,9 @@
   @GenerateTests(rootdir='tests/cxx', pattern='*.cc')
   class cxx(unittest.TestCase): pass
 
+  @GenerateTests(rootdir='tests/driver', pattern='*.c')
+  class driver(unittest.TestCase): pass
+
   if runner_args.list_tests:
     exit(PrintLoadedTests())
   elif runner_args.list_test_files:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/tests/cxx/consteval.cc 
new/include-what-you-use/tests/cxx/consteval.cc
--- old/include-what-you-use/tests/cxx/consteval.cc     1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/cxx/consteval.cc     2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,51 @@
+//===--- consteval.cc - test input file for iwyu 
--------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I . -std=c++20
+
+// These tests are not particularly interesting in themselves, but they cover 
an
+// upstream bug in Clang (https://github.com/llvm/llvm-project/issues/53044) 
for
+// which we have a workaround.
+
+#include "tests/cxx/direct.h"
+
+struct X {
+  // IWYU: IndirectClass needs a declaration
+  consteval X(const IndirectClass& v) {
+  }
+
+  // IWYU: IndirectClass needs a declaration
+  consteval operator IndirectClass*() const {
+    return nullptr;
+  }
+};
+
+void t() {
+  // Pass value through Consteval conversion constructor.
+  // IWYU: IndirectClass is...*indirect.h
+  IndirectClass a;
+  X x = a;
+
+  // Try an implicit consteval user-defined conversion too.
+  // IWYU: IndirectClass needs a declaration
+  IndirectClass* b = x;
+}
+
+/**** IWYU_SUMMARY
+
+tests/cxx/consteval.cc should add these lines:
+#include "tests/cxx/indirect.h"
+
+tests/cxx/consteval.cc should remove these lines:
+- #include "tests/cxx/direct.h"  // lines XX-XX
+
+The full include-list for tests/cxx/consteval.cc:
+#include "tests/cxx/indirect.h"  // for IndirectClass
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/tests/driver/direct.h 
new/include-what-you-use/tests/driver/direct.h
--- old/include-what-you-use/tests/driver/direct.h      1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/direct.h      2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,15 @@
+//===--- direct.h - test input file for iwyu 
------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INCLUDE_WHAT_YOU_USE_TESTS_DRIVER_DIRECT_H_
+#define INCLUDE_WHAT_YOU_USE_TESTS_DRIVER_DIRECT_H_
+
+#include "tests/driver/indirect.h"
+
+#endif  // INCLUDE_WHAT_YOU_USE_TESTS_DRIVER_DIRECT_H_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_bad_args.c 
new/include-what-you-use/tests/driver/exitcode_bad_args.c
--- old/include-what-you-use/tests/driver/exitcode_bad_args.c   1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_bad_args.c   2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,16 @@
+//===--- exitcode_bad_args.c - test input file for iwyu 
-------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -some -unsupported -Xiwyu -arguments
+
+// When argument parsing fails, IWYU exits with code 1.
+
+/**** IWYU_SUMMARY(1)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/tests/driver/exitcode_good.c 
new/include-what-you-use/tests/driver/exitcode_good.c
--- old/include-what-you-use/tests/driver/exitcode_good.c       1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_good.c       2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,16 @@
+//===--- exitcode_good.c - test input file for iwyu 
-----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Tests that IWYU exits with code 0 when no suggestions are made.
+
+/**** IWYU_SUMMARY(0)
+
+(tests/driver/exitcode_good.c has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_good_error.c 
new/include-what-you-use/tests/driver/exitcode_good_error.c
--- old/include-what-you-use/tests/driver/exitcode_good_error.c 1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_good_error.c 2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,19 @@
+//===--- exitcode_good_error.c - test input file for iwyu 
-----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -Xiwyu --error
+
+// When --error is provided, IWYU exits with error only if analysis finds IWYU
+// violations. In this case there are none, so IWYU exits with 0.
+
+/**** IWYU_SUMMARY(0)
+
+(tests/driver/exitcode_good_error.c has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_good_error_always.c 
new/include-what-you-use/tests/driver/exitcode_good_error_always.c
--- old/include-what-you-use/tests/driver/exitcode_good_error_always.c  
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_good_error_always.c  
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,19 @@
+//===--- exitcode_good_error_always.c - test input file for iwyu 
----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -Xiwyu --error_always
+
+// When --error_always is provided, IWYU exits with error even if analysis
+// succeeds.
+
+/**** IWYU_SUMMARY(1)
+
+(tests/driver/exitcode_good_error_always.c has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_good_error_always_arg.c 
new/include-what-you-use/tests/driver/exitcode_good_error_always_arg.c
--- old/include-what-you-use/tests/driver/exitcode_good_error_always_arg.c      
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_good_error_always_arg.c      
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,19 @@
+//===--- exitcode_good_error_always_arg.c - test input file for iwyu 
------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -Xiwyu --error_always=100
+
+// When --error_always is provided, IWYU exits with error even if analysis
+// succeeds.
+
+/**** IWYU_SUMMARY(100)
+
+(tests/driver/exitcode_good_error_always_arg.c has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_good_error_and_always.c 
new/include-what-you-use/tests/driver/exitcode_good_error_and_always.c
--- old/include-what-you-use/tests/driver/exitcode_good_error_and_always.c      
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_good_error_and_always.c      
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,18 @@
+//===--- exitcode_good_error_and_always.c - test input file for iwyu 
------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -Xiwyu --error=19 -Xiwyu --error_always=91
+
+// When both are provided, --error_always takes precedence
+
+/**** IWYU_SUMMARY(91)
+
+(tests/driver/exitcode_good_error_and_always.c has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_good_error_arg.c 
new/include-what-you-use/tests/driver/exitcode_good_error_arg.c
--- old/include-what-you-use/tests/driver/exitcode_good_error_arg.c     
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_good_error_arg.c     
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,19 @@
+//===--- exitcode_good_error_arg.c - test input file for iwyu 
-------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -Xiwyu --error=100
+
+// When --error is provided, IWYU exits with error only if analysis finds IWYU
+// violations. In this case there are none, so IWYU exits with 0.
+
+/**** IWYU_SUMMARY(0)
+
+(tests/driver/exitcode_good_error_arg.c has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_syntax_error.c 
new/include-what-you-use/tests/driver/exitcode_syntax_error.c
--- old/include-what-you-use/tests/driver/exitcode_syntax_error.c       
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_syntax_error.c       
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,19 @@
+//===--- exitcode_syntax_error.c - test input file for iwyu 
---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Tests that IWYU exits with code 1 when Clang fails to parse the provided
+// source code.
+
+// IWYU: expected ';' after top level declarator
+// IWYU: unknown type name 'this'
+this is not valid C code;
+
+/**** IWYU_SUMMARY(1)
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/tests/driver/exitcode_warn.c 
new/include-what-you-use/tests/driver/exitcode_warn.c
--- old/include-what-you-use/tests/driver/exitcode_warn.c       1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_warn.c       2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,30 @@
+//===--- exitcode_warn.c - test input file for iwyu 
-----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I .
+
+// By default, if IWYU finds policy violations it exits with code 0.
+
+#include "tests/driver/direct.h"
+
+// IWYU: Indirect is...*indirect.h
+struct Indirect x;
+
+/**** IWYU_SUMMARY(0)
+
+tests/driver/exitcode_warn.c should add these lines:
+#include "tests/driver/indirect.h"
+
+tests/driver/exitcode_warn.c should remove these lines:
+- #include "tests/driver/direct.h"  // lines XX-XX
+
+The full include-list for tests/driver/exitcode_warn.c:
+#include "tests/driver/indirect.h"  // for Indirect
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_warn_error.c 
new/include-what-you-use/tests/driver/exitcode_warn_error.c
--- old/include-what-you-use/tests/driver/exitcode_warn_error.c 1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_warn_error.c 2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,31 @@
+//===--- exitcode_warn_error.c - test input file for iwyu 
-----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I . -Xiwyu --error
+
+// When --error is provided, IWYU exits with error if analysis finds IWYU
+// violations. Default exit code is 1.
+
+#include "tests/driver/direct.h"
+
+// IWYU: Indirect is...*indirect.h
+struct Indirect x;
+
+/**** IWYU_SUMMARY(1)
+
+tests/driver/exitcode_warn_error.c should add these lines:
+#include "tests/driver/indirect.h"
+
+tests/driver/exitcode_warn_error.c should remove these lines:
+- #include "tests/driver/direct.h"  // lines XX-XX
+
+The full include-list for tests/driver/exitcode_warn_error.c:
+#include "tests/driver/indirect.h"  // for Indirect
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_warn_error_always.c 
new/include-what-you-use/tests/driver/exitcode_warn_error_always.c
--- old/include-what-you-use/tests/driver/exitcode_warn_error_always.c  
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_warn_error_always.c  
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,32 @@
+//===--- exitcode_warn_error_always.c - test input file for iwyu 
----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I . -Xiwyu --error_always
+
+// When --error_always is provided, IWYU exits with error whether or not there
+// are IWYU violations. See exitcode_good_error_always.c for complementary
+// testcase where there are no violations.
+
+#include "tests/driver/direct.h"
+
+// IWYU: Indirect is...*indirect.h
+struct Indirect x;
+
+/**** IWYU_SUMMARY(1)
+
+tests/driver/exitcode_warn_error_always.c should add these lines:
+#include "tests/driver/indirect.h"
+
+tests/driver/exitcode_warn_error_always.c should remove these lines:
+- #include "tests/driver/direct.h"  // lines XX-XX
+
+The full include-list for tests/driver/exitcode_warn_error_always.c:
+#include "tests/driver/indirect.h"  // for Indirect
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_warn_error_always_arg.c 
new/include-what-you-use/tests/driver/exitcode_warn_error_always_arg.c
--- old/include-what-you-use/tests/driver/exitcode_warn_error_always_arg.c      
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_warn_error_always_arg.c      
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,32 @@
+//===--- exitcode_warn_error_always_arg.c - test input file for iwyu 
------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I . -Xiwyu --error_always=11
+
+// When --error_always is provided, IWYU exits with error whether or not there
+// are IWYU violations. See exitcode_good_error_always_arg.c for complementary
+// testcase where there are no violations.
+
+#include "tests/driver/direct.h"
+
+// IWYU: Indirect is...*indirect.h
+struct Indirect x;
+
+/**** IWYU_SUMMARY(11)
+
+tests/driver/exitcode_warn_error_always_arg.c should add these lines:
+#include "tests/driver/indirect.h"
+
+tests/driver/exitcode_warn_error_always_arg.c should remove these lines:
+- #include "tests/driver/direct.h"  // lines XX-XX
+
+The full include-list for tests/driver/exitcode_warn_error_always_arg.c:
+#include "tests/driver/indirect.h"  // for Indirect
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_warn_error_and_always.c 
new/include-what-you-use/tests/driver/exitcode_warn_error_and_always.c
--- old/include-what-you-use/tests/driver/exitcode_warn_error_and_always.c      
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_warn_error_and_always.c      
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,30 @@
+//===--- exitcode_warn_error_and_always.c - test input file for iwyu 
------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I . -Xiwyu --error=15 -Xiwyu --error_always=51
+
+// When both are provided, --error_always takes precedence
+
+#include "tests/driver/direct.h"
+
+// IWYU: Indirect is...*indirect.h
+struct Indirect x;
+
+/**** IWYU_SUMMARY(51)
+
+tests/driver/exitcode_warn_error_and_always.c should add these lines:
+#include "tests/driver/indirect.h"
+
+tests/driver/exitcode_warn_error_and_always.c should remove these lines:
+- #include "tests/driver/direct.h"  // lines XX-XX
+
+The full include-list for tests/driver/exitcode_warn_error_and_always.c:
+#include "tests/driver/indirect.h"  // for Indirect
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/include-what-you-use/tests/driver/exitcode_warn_error_arg.c 
new/include-what-you-use/tests/driver/exitcode_warn_error_arg.c
--- old/include-what-you-use/tests/driver/exitcode_warn_error_arg.c     
1970-01-01 01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/exitcode_warn_error_arg.c     
2022-03-29 20:31:46.000000000 +0200
@@ -0,0 +1,31 @@
+//===--- exitcode_warn_error_arg.c - test input file for iwyu 
-------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// IWYU_ARGS: -I . -Xiwyu --error=42
+
+// When --error is provided, IWYU exits with error if analysis finds IWYU
+// violations.
+
+#include "tests/driver/direct.h"
+
+// IWYU: Indirect is...*indirect.h
+struct Indirect x;
+
+/**** IWYU_SUMMARY(42)
+
+tests/driver/exitcode_warn_error_arg.c should add these lines:
+#include "tests/driver/indirect.h"
+
+tests/driver/exitcode_warn_error_arg.c should remove these lines:
+- #include "tests/driver/direct.h"  // lines XX-XX
+
+The full include-list for tests/driver/exitcode_warn_error_arg.c:
+#include "tests/driver/indirect.h"  // for Indirect
+
+***** IWYU_SUMMARY */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/include-what-you-use/tests/driver/indirect.h 
new/include-what-you-use/tests/driver/indirect.h
--- old/include-what-you-use/tests/driver/indirect.h    1970-01-01 
01:00:00.000000000 +0100
+++ new/include-what-you-use/tests/driver/indirect.h    2022-03-29 
20:31:46.000000000 +0200
@@ -0,0 +1,17 @@
+//===--- indirect.h - test input file for iwyu 
----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INCLUDE_WHAT_YOU_USE_TESTS_DRIVER_INDIRECT_H_
+#define INCLUDE_WHAT_YOU_USE_TESTS_DRIVER_INDIRECT_H_
+
+struct Indirect {
+  int a;
+};
+
+#endif  // INCLUDE_WHAT_YOU_USE_TESTS_DRIVER_INDIRECT_H_

Reply via email to