Author: mitchell Date: 2026-02-14T00:30:51+08:00 New Revision: 04fbb1dba583919939eafeb0ec6241e062e61371
URL: https://github.com/llvm/llvm-project/commit/04fbb1dba583919939eafeb0ec6241e062e61371 DIFF: https://github.com/llvm/llvm-project/commit/04fbb1dba583919939eafeb0ec6241e062e61371.diff LOG: [clang-tidy] Header check support for check_clang_tidy.py (#175735) As of AI-Usage: Gemini CLI was used for pre-commit review and finding testcases that need to be updated. Closes [#133515](https://github.com/llvm/llvm-project/issues/133515) --------- Co-authored-by: EugeneZelenko <[email protected]> Added: Modified: clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/check_clang_tidy.py clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header-with-fix.h clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header.h clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-header.cpp clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-multi-fixes.cpp clang-tools-extra/test/clang-tidy/checkers/performance/Inputs/unnecessary-value-param/header.h clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-header.cpp clang-tools-extra/test/clang-tidy/checkers/readability/duplicate-include.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 36626d7c1a9be..5c0060877a67f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -94,6 +94,11 @@ Improvements to clang-query Improvements to clang-tidy -------------------------- +- Improved :program:`check_clang_tidy.py` script by adding the `-check-header` + argument to simplify testing of header files. This argument automatically + manages the creation of temporary header files and ensures that diagnostics + and fixes are verified for the specified headers. + New checks ^^^^^^^^^^ diff --git a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py index 4e42f0b12516b..62377a1ccbf1b 100755 --- a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py +++ b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py @@ -49,7 +49,8 @@ import re import subprocess import sys -from typing import List, Tuple +from collections import defaultdict +from typing import Dict, List, Sequence, Tuple def write_file(file_name: str, text: str) -> None: @@ -93,7 +94,8 @@ def __init__(self, args: argparse.Namespace, extra_args: List[str]) -> None: self.input_file_name = args.input_file_name self.check_name = args.check_name self.temp_file_name = args.temp_file_name - self.original_file_name = self.temp_file_name + ".orig" + self.check_headers = args.check_headers + self.original_file_name = f"{self.temp_file_name}.orig" self.expect_clang_tidy_error = args.expect_clang_tidy_error self.std = args.std self.check_suffix = args.check_suffix @@ -121,6 +123,18 @@ def __init__(self, args: argparse.Namespace, extra_args: List[str]) -> None: self.clang_extra_args = self.clang_tidy_extra_args[i + 1 :] self.clang_tidy_extra_args = self.clang_tidy_extra_args[:i] + self.check_header_map: Dict[str, str] = {} + self.header_dir = f"{self.temp_file_name}.headers" + if self.check_headers: + self.check_header_map = { + os.path.normcase( + os.path.abspath(os.path.join(self.header_dir, os.path.basename(h))) + ): os.path.abspath(h) + for h in self.check_headers + } + + self.clang_extra_args.insert(0, f"-I{self.header_dir}") + # If the test does not specify a config style, force an empty one; otherwise # auto-detection logic can discover a ".clang-tidy" file that is not related to # the test. @@ -136,7 +150,7 @@ def __init__(self, args: argparse.Namespace, extra_args: List[str]) -> None: "-fblocks", ] + self.clang_extra_args - self.clang_extra_args.append("-std=" + self.std) + self.clang_extra_args.append(f"-std={self.std}") # Tests should not rely on STL being available, and instead provide mock # implementations of relevant APIs. @@ -158,8 +172,8 @@ def get_prefixes(self) -> None: for suffix in self.check_suffix: if suffix and not re.match("^[A-Z0-9\\-]+$", suffix): sys.exit( - 'Only A..Z, 0..9 and "-" are allowed in check suffixes list,' - + ' but "%s" was given' % suffix + 'Only A..Z, 0..9 and "-" are allowed in check suffixes list, ' + f'but "{suffix}" was given' ) file_check_suffix = ("-" + suffix) if suffix else "" @@ -196,15 +210,50 @@ def get_prefixes(self) -> None: ) assert expect_diagnosis or self.expect_no_diagnosis - def prepare_test_inputs(self) -> None: + def _remove_filecheck_content(self, text: str) -> str: # Remove the contents of the CHECK lines to avoid CHECKs matching on - # themselves. We need to keep the comments to preserve line numbers while + # themselves. We need to keep the comments to preserve line numbers while # avoiding empty lines which could potentially trigger formatting-related # checks. - cleaned_test = re.sub("// *CHECK-[A-Z0-9\\-]*:[^\r\n]*", "//", self.input_text) + return re.sub("// *CHECK-[A-Z0-9\\-]*:[^\r\n]*", "//", text) + + def _filter_prefixes(self, prefixes: Sequence[str], check_file: str) -> List[str]: + """ + Filter prefixes to only those present in the check file. + + - Input: + prefixes: A list of potential FileCheck prefixes. + check_file: The file to check for prefix presence. + - Output: + A list of prefixes found in the check file. + + FileCheck fails if a specified prefix is not present. This is common + in header testing scenarios where expectations diff er between the + main file and the header (e.g. the main file might verify code + changes while the header only verifies warnings). + """ + if check_file == self.input_file_name: + content = self.input_text + else: + with open(check_file, "r", encoding="utf-8") as f: + content = f.read() + return [p for p in prefixes if p in content] + + def prepare_test_inputs(self) -> None: + cleaned_test = self._remove_filecheck_content(self.input_text) write_file(self.temp_file_name, cleaned_test) write_file(self.original_file_name, cleaned_test) + if self.check_headers: + os.makedirs(self.header_dir, exist_ok=True) + + for temp_header_path, header in self.check_header_map.items(): + with open(header, "r", encoding="utf-8") as f: + cleaned_header = self._remove_filecheck_content(f.read()) + + write_file(temp_header_path, cleaned_header) + write_file(f"{temp_header_path}.orig", cleaned_header) + def run_clang_tidy(self) -> str: args = ( [ @@ -216,11 +265,11 @@ def run_clang_tidy(self) -> str: ( "-fix" if self.export_fixes is None - else "--export-fixes=" + self.export_fixes + else f"--export-fixes={self.export_fixes}" ) ] + [ - "--checks=-*," + self.check_name, + f"--checks=-*,{self.check_name}", ] + self.clang_tidy_extra_args + ["--"] @@ -228,7 +277,7 @@ def run_clang_tidy(self) -> str: ) if self.expect_clang_tidy_error: args.insert(0, "not") - print("Running " + repr(args) + "...") + print(f"Running {repr(args)}...") clang_tidy_output = try_run(args) print("------------------------ clang-tidy output -----------------------") print( @@ -241,6 +290,12 @@ def run_clang_tidy(self) -> str: diff _output = try_run( [" diff ", "-u", self.original_file_name, self.temp_file_name], False ) + if self.check_headers: + for temp_header_path in self.check_header_map: + diff _output += try_run( + [" diff ", "-u", f"{temp_header_path}.orig", temp_header_path], False + ) + print("------------------------------ Fixes -----------------------------") print( diff _output) print("------------------------------------------------------------------") @@ -250,39 +305,61 @@ def check_no_diagnosis(self, clang_tidy_output: str) -> None: if clang_tidy_output != "": sys.exit("No diagnostics were expected, but found the ones above") - def check_fixes(self) -> None: - if self.has_check_fixes: - try_run( - [ - "FileCheck", - "--input-file=" + self.temp_file_name, - self.input_file_name, - "--check-prefixes=" + ",".join(self.fixes.prefixes), - ( - "--match-full-lines" - if not self.match_partial_fixes - else "--strict-whitespace" # Keeping past behavior. - ), - ] - ) + def check_fixes(self, input_file: str = "", check_file: str = "") -> None: + if not (check_file or self.has_check_fixes): + return - def check_messages(self, clang_tidy_output: str) -> None: - if self.has_check_messages: - messages_file = self.temp_file_name + ".msg" - write_file(messages_file, clang_tidy_output) - try_run( - [ - "FileCheck", - "-input-file=" + messages_file, - self.input_file_name, - "-check-prefixes=" + ",".join(self.messages.prefixes), - "-implicit-check-not={{warning|error}}:", - ] - ) + input_file = input_file or self.temp_file_name + check_file = check_file or self.input_file_name + active_prefixes = self._filter_prefixes(self.fixes.prefixes, check_file) + + if not active_prefixes: + return + + try_run( + [ + "FileCheck", + f"--input-file={input_file}", + check_file, + f"--check-prefixes={','.join(active_prefixes)}", + ( + "--strict-whitespace" # Keeping past behavior. + if self.match_partial_fixes + else "--match-full-lines" + ), + ] + ) + + def check_messages( + self, + clang_tidy_output: str, + messages_file: str = "", + check_file: str = "", + ) -> None: + if not check_file and not self.has_check_messages: + return + + messages_file = messages_file or f"{self.temp_file_name}.msg" + check_file = check_file or self.input_file_name + + active_prefixes = self._filter_prefixes(self.messages.prefixes, check_file) + if not active_prefixes: + return + + write_file(messages_file, clang_tidy_output) + try_run( + [ + "FileCheck", + f"-input-file={messages_file}", + check_file, + f"-check-prefixes={','.join(active_prefixes)}", + "-implicit-check-not={{warning|error}}:", + ] + ) def check_notes(self, clang_tidy_output: str) -> None: if self.has_check_notes: - notes_file = self.temp_file_name + ".notes" + notes_file = f"{self.temp_file_name}.notes" filtered_output = [ line for line in clang_tidy_output.splitlines() @@ -292,25 +369,74 @@ def check_notes(self, clang_tidy_output: str) -> None: try_run( [ "FileCheck", - "-input-file=" + notes_file, + f"-input-file={notes_file}", self.input_file_name, - "-check-prefixes=" + ",".join(self.notes.prefixes), + f"-check-prefixes={','.join(self.notes.prefixes)}", "-implicit-check-not={{note|warning|error}}:", ] ) + def _separate_messages(self, clang_tidy_output: str) -> Tuple[str, Dict[str, str]]: + """ + Separates diagnostics for the main file and headers. + + - Input: The raw diagnostic output from clang-tidy. + - Output: A tuple containing: + 1. The diagnostic output for the main file. + 2. A dictionary mapping header files to their diagnostics. + """ + if not self.check_headers: + return clang_tidy_output, {} + + header_messages = defaultdict(list) + remaining_lines: List[str] = [] + current_file = "" + + for line in clang_tidy_output.splitlines(keepends=True): + if re.match(r"^\d+ warnings? generated\.", line): + continue + + # Matches the beginning of a clang-tidy diagnostic line, + # which starts with "file_path:line:col: ". + if match := re.match(r"^(.+):\d+:\d+: ", line): + abs_path = os.path.normcase(os.path.abspath(match.group(1))) + current_file = abs_path if abs_path in self.check_header_map else "" + + dest_list = ( + header_messages[current_file] if current_file else remaining_lines + ) + dest_list.append(line) + + header_messages_str = {k: "".join(v) for k, v in header_messages.items()} + return "".join(remaining_lines), header_messages_str + def run(self) -> None: self.read_input() if self.export_fixes is None: self.get_prefixes() self.prepare_test_inputs() clang_tidy_output = self.run_clang_tidy() + main_output, header_messages = self._separate_messages(clang_tidy_output) + if self.expect_no_diagnosis: - self.check_no_diagnosis(clang_tidy_output) + self.check_no_diagnosis(main_output) elif self.export_fixes is None: self.check_fixes() - self.check_messages(clang_tidy_output) - self.check_notes(clang_tidy_output) + self.check_messages(main_output) + self.check_notes(main_output) + + for temp_header, original_header in self.check_header_map.items(): + self.check_fixes( + input_file=temp_header, + check_file=original_header, + ) + + if temp_header in header_messages: + self.check_messages( + header_messages[temp_header], + messages_file=f"{temp_header}.msg", + check_file=original_header, + ) CPP_STANDARDS = [ @@ -370,6 +496,13 @@ def parse_arguments() -> Tuple[argparse.Namespace, List[str]]: type=csv, help="comma-separated list of FileCheck suffixes", ) + parser.add_argument( + "-check-header", + action="append", + dest="check_headers", + default=[], + help="Header files to check", + ) parser.add_argument( "-export-fixes", default=None, diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h index 703d7e05ca2e9..0d748a81c0067 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h @@ -1,8 +1,9 @@ +// CHECK-MESSAGES-NORMAL: :[[@LINE+1]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] namespace nn1 { namespace nn2 { -// CHECK-FIXES: namespace nn1::nn2 +// CHECK-FIXES-NORMAL: namespace nn1::nn2 { void t(); } // namespace nn2 } // namespace nn1 -// CHECK-FIXES: void t(); -// CHECK-FIXES-NEXT: } // namespace nn1::nn2 +// CHECK-FIXES-NORMAL: void t(); +// CHECK-FIXES-NORMAL-NEXT: } // namespace nn1::nn2 diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header-with-fix.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header-with-fix.h index 62609e25f682a..98512f411fe61 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header-with-fix.h +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header-with-fix.h @@ -4,5 +4,6 @@ struct S { }; struct Foo { Foo(const S &s); + // CHECK-FIXES: Foo(S s); S s; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header.h index c2103cb3fc7a1..e27104e70ac0b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header.h +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/pass-by-value/header.h @@ -6,5 +6,8 @@ class ThreadId { struct A { A(const ThreadId &tid) : threadid(tid) {} + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move [modernize-pass-by-value] + // CHECK-FIXES: #include <utility> + // CHECK-FIXES: A(ThreadId tid) : threadid(std::move(tid)) {} ThreadId threadid; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp index 35cb5503ba245..4326fa6412021 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp @@ -1,14 +1,7 @@ -// RUN: mkdir -p %t.dir -// RUN: cp %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %t.dir/modernize-concat-nested-namespaces.h -// RUN: %check_clang_tidy -std=c++17 -check-suffix=NORMAL %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir -// RUN: FileCheck -input-file=%t.dir/modernize-concat-nested-namespaces.h %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES -// Restore header file and re-run with c++20: -// RUN: cp %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %t.dir/modernize-concat-nested-namespaces.h -// RUN: %check_clang_tidy -std=c++20 -check-suffixes=NORMAL,CPP20 %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir -// RUN: FileCheck -input-file=%t.dir/modernize-concat-nested-namespaces.h %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES +// RUN: %check_clang_tidy -std=c++17 -check-suffix=NORMAL -check-header %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %s modernize-concat-nested-namespaces %t +// RUN: %check_clang_tidy -std=c++20 -check-suffixes=NORMAL,CPP20 -check-header %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %s modernize-concat-nested-namespaces %t #include "modernize-concat-nested-namespaces.h" -// CHECK-MESSAGES-NORMAL-DAG: modernize-concat-nested-namespaces.h:1:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] namespace n1 {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-header.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-header.cpp index 461a6378d99c0..e40c21f632d1a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-header.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-header.cpp @@ -1,10 +1,5 @@ -// RUN: mkdir -p %t.dir -// RUN: cp %S/Inputs/pass-by-value/header.h %t.dir/pass-by-value-header.h -// RUN: clang-tidy %s -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %t.dir | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:" -// RUN: FileCheck -input-file=%t.dir/pass-by-value-header.h %s -check-prefix=CHECK-FIXES -// FIXME: Make the test work in all language modes. +// RUN: %check_clang_tidy -check-header %S/Inputs/pass-by-value/header.h \ +// RUN: %s modernize-pass-by-value %t -- -- -std=c++11 -#include "pass-by-value-header.h" -// CHECK-MESSAGES: :8:5: warning: pass by value and use std::move [modernize-pass-by-value] -// CHECK-FIXES: #include <utility> -// CHECK-FIXES: A(ThreadId tid) : threadid(std::move(tid)) {} +#include "header.h" +// FIXME: Make the test work in all language modes. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-multi-fixes.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-multi-fixes.cpp index b77c74be02f5f..bbe96d39793b0 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-multi-fixes.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value-multi-fixes.cpp @@ -1,13 +1,9 @@ -// RUN: mkdir -p %t.dir -// RUN: cat %S/Inputs/pass-by-value/header-with-fix.h > %t.dir/pass-by-value-header-with-fix.h -// RUN: sed -e 's#//.*$##' %s > %t.dir/code.cpp -// RUN: clang-tidy %t.dir/code.cpp -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %t.dir | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:" -// RUN: FileCheck -input-file=%t.dir/code.cpp %s -check-prefix=CHECK-FIXES -// RUN: FileCheck -input-file=%t.dir/pass-by-value-header-with-fix.h %s -check-prefix=CHECK-HEADER-FIXES +// RUN: %check_clang_tidy -check-header %S/Inputs/pass-by-value/header-with-fix.h \ +// RUN: %s modernize-pass-by-value %t -- -- -std=c++11 -#include "pass-by-value-header-with-fix.h" -// CHECK-HEADER-FIXES: Foo(S s); +#include "header-with-fix.h" + +// CHECK-MESSAGES: :[[@LINE+1]]:10: warning: pass by value and use std::move [modernize-pass-by-value] Foo::Foo(const S &s) : s(s) {} -// CHECK-MESSAGES: :10:10: warning: pass by value and use std::move [modernize-pass-by-value] // CHECK-FIXES: #include <utility> // CHECK-FIXES: Foo::Foo(S s) : s(std::move(s)) {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/Inputs/unnecessary-value-param/header.h b/clang-tools-extra/test/clang-tidy/checkers/performance/Inputs/unnecessary-value-param/header.h index d6f6e65ace79d..32b3d3374bc59 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/Inputs/unnecessary-value-param/header.h +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/Inputs/unnecessary-value-param/header.h @@ -7,9 +7,11 @@ struct ABC { int f1(int n, ABC v1, ABC v2); // line 9 +// CHECK-FIXES: int f1(int n, const ABC& v1, const ABC& v2); // line 9 int f1(int n, ABC v1); // line 11 void f2( int n, ABC v2); // line 15 +// CHECK-FIXES: void f2( int n, const ABC& v2); // line 15 diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-header.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-header.cpp index a7fc1eace67c5..4e53a385af629 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-header.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-header.cpp @@ -1,8 +1,5 @@ -// RUN: rm -rf %t -// RUN: mkdir %t -// RUN: cp %S/Inputs/unnecessary-value-param/header.h %t/header.h -// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t/temp -- -- -I %t -// RUN: diff %t/header.h %S/Inputs/unnecessary-value-param/header-fixed.h +// RUN: %check_clang_tidy -check-header %S/Inputs/unnecessary-value-param/header.h \ +// RUN: %s performance-unnecessary-value-param %t #include "header.h" diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/duplicate-include.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/duplicate-include.cpp index c452f69fad07d..13c54dac16e05 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/duplicate-include.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/duplicate-include.cpp @@ -1,5 +1,5 @@ -// RUN: %check_clang_tidy %s readability-duplicate-include %t -- \ -// RUN: -header-filter='' \ +// RUN: %check_clang_tidy -check-header %S/Inputs/duplicate-include/duplicate-include.h \ +// RUN: %s readability-duplicate-include %t -- \ // RUN: -- -isystem %S/Inputs/duplicate-include/system -I %S/Inputs/duplicate-include int a; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
