Skip to content

[clang-tidy] HeaderFilterRegex does not work if .clang-tidy is in subdirectory #133453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tearfur opened this issue Mar 28, 2025 · 2 comments · Fixed by #133582
Closed

[clang-tidy] HeaderFilterRegex does not work if .clang-tidy is in subdirectory #133453

tearfur opened this issue Mar 28, 2025 · 2 comments · Fixed by #133582

Comments

@tearfur
Copy link

tearfur commented Mar 28, 2025

Specifying HeaderFilterRegex: .* in the .clang-tidy file in a subdirectory doesn't seem to take effect during compilation, but running clang-tidy --dump-config in the subdirectory does show HeaderFilterRegex: '.*'.

It works as expected if I move the .clang-tidy file to the project root, then clean and build.

The output of running clang-tidy --dump-config in the subdirectory is the same no matter .clang-tidy is placed in the project root or the subdirectory.

This CMake project demonstrates the issue:

header_filter_subdir.zip

Here are my detailed reproduce steps

Only relevant command output are shown.

In host machine

$ docker run -it fedora:41 bash
$ docker cp header_filter_subdir/ ${CONTAINER}:/root

In Docker container

# cd
# dnf update
# dnf install @c-development cmake git ninja-build
# git clone https://github.com/llvm/llvm-project.git
# cd llvm-project/
# cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra' -DCMAKE_BUILD_TYPE=Release
# cd build/
# cmake --build .
# cmake --install .
# clang --version
clang version 21.0.0git (https://github.com/llvm/llvm-project.git 316bb89c942c1a1cf61d3e673030f82d6f0b8acf)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
# cd ~/header_filter_subdir/
# CC=clang CXX=clang++ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is Clang 21.0.0
-- The CXX compiler identification is Clang 21.0.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for clang-tidy
-- Looking for clang-tidy - found
'/usr/local/bin/clang-tidy' '--version'
LLVM (http://llvm.org/):
  LLVM version 21.0.0git
  Optimized build.
-- Configuring done (0.3s)
-- Generating done (0.0s)
-- Build files have been written to: /root/header_filter_subdir/build
# cd build/
# cmake --build .
[2/4] Building CXX object print/CMakeFiles/my_print.dir/print.cpp.o
/root/header_filter_subdir/print/print.cpp:5:21: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    5 | void print_impl(int const i);
      |                     ^~~~~
[4/4] Linking CXX executable header_filter_subdir
# cd ../print/
# clang-tidy --dump-config | tee subdir.out
# mv .clang-tidy ..
# cd -
/root/header_filter_subdir/build
# cmake --build . --target clean
# cmake --build .
[1/4] Building CXX object CMakeFiles/header_filter_subdir.dir/main.cpp.o
/root/header_filter_subdir/print/print.h:4:16: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    4 | void print(int const i);
      |                ^~~~~
[2/4] Building CXX object print/CMakeFiles/my_print.dir/print.cpp.o
/root/header_filter_subdir/print/print.cpp:5:21: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    5 | void print_impl(int const i);
      |                     ^~~~~
/root/header_filter_subdir/print/print.h:4:16: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    4 | void print(int const i);
      |                ^~~~~
[4/4] Linking CXX executable header_filter_subdir
# cd -
/root/header_filter_subdir/print
# clang-tidy --dump-config | tee rootdir.out
# diff subdir.out rootdir.out # no output
# grep -P ^HeaderFilterRegex subdir.out
HeaderFilterRegex: '.*'
@tearfur tearfur changed the title HeaderFilterRegex does not work if .clang-tidy is in subdirectory [clang-tidy] HeaderFilterRegex does not work if .clang-tidy is in subdirectory Mar 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 28, 2025

@llvm/issue-subscribers-clang-tidy

Author: Yat Ho (tearfur)

Specifying `HeaderFilterRegex: .*` in the `.clang-tidy` file in a subdirectory doesn't seem to take effect during compilation, but running `clang-tidy --dump-config` in the subdirectory does show `HeaderFilterRegex: '.*'`.

It works as expected if I move the .clang-tidy file to the project root, then clean and build.

The output of running clang-tidy --dump-config in the subdirectory is the same no matter .clang-tidy is placed in the project root or the subdirectory.

This CMake project demonstrates the issue:

header_filter_subdir.zip

<details>
<summary>Here are my detailed reproduce steps</summary>

Only relevant command output are shown.

In host machine

$ docker run -it fedora:41 bash
$ docker cp header_filter_subdir/ ${CONTAINER}:/root

In Docker container

# cd
# dnf update
# dnf install @<!-- -->c-development cmake git ninja-build
# git clone https://github.com/llvm/llvm-project.git
# cd llvm-project/
# cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra' -DCMAKE_BUILD_TYPE=Release
# cd build/
# cmake --build .
# cmake --install .
# clang --version
clang version 21.0.0git (https://github.com/llvm/llvm-project.git 316bb89c942c1a1cf61d3e673030f82d6f0b8acf)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
# cd ~/header_filter_subdir/
# CC=clang CXX=clang++ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is Clang 21.0.0
-- The CXX compiler identification is Clang 21.0.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for clang-tidy
-- Looking for clang-tidy - found
'/usr/local/bin/clang-tidy' '--version'
LLVM (http://llvm.org/):
  LLVM version 21.0.0git
  Optimized build.
-- Configuring done (0.3s)
-- Generating done (0.0s)
-- Build files have been written to: /root/header_filter_subdir/build
# cd build/
# cmake --build .
[2/4] Building CXX object print/CMakeFiles/my_print.dir/print.cpp.o
/root/header_filter_subdir/print/print.cpp:5:21: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    5 | void print_impl(int const i);
      |                     ^~~~~
[4/4] Linking CXX executable header_filter_subdir
# cd ../print/
# clang-tidy --dump-config | tee subdir.out
# mv .clang-tidy ..
# cd -
/root/header_filter_subdir/build
# cmake --build . --target clean
# cmake --build .
[1/4] Building CXX object CMakeFiles/header_filter_subdir.dir/main.cpp.o
/root/header_filter_subdir/print/print.h:4:16: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    4 | void print(int const i);
      |                ^~~~~
[2/4] Building CXX object print/CMakeFiles/my_print.dir/print.cpp.o
/root/header_filter_subdir/print/print.cpp:5:21: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    5 | void print_impl(int const i);
      |                     ^~~~~
/root/header_filter_subdir/print/print.h:4:16: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
    4 | void print(int const i);
      |                ^~~~~
[4/4] Linking CXX executable header_filter_subdir
# cd -
/root/header_filter_subdir/print
# clang-tidy --dump-config | tee rootdir.out
# diff subdir.out rootdir.out # no output
# grep -P ^HeaderFilterRegex subdir.out
HeaderFilterRegex: '.*'

</details>

@vbvictor
Copy link
Contributor

Looks like duplicate of #121969 and #118009

carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 29, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 29, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 29, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 29, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 29, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 29, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 30, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Mar 30, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
@carlosgalvezp carlosgalvezp added this to the LLVM 20.X Release milestone Apr 2, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Apr 2, 2025
carlosgalvezp pushed a commit to carlosgalvezp/llvm-project that referenced this issue Apr 3, 2025
PR llvm#91400 broke the usage
of HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created
upon calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in
the future:

- One of them, "simple", tests the most basic use case with a single
  top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
  gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009, llvm#121969, llvm#133453
@github-project-automation github-project-automation bot moved this from Needs Triage to Done in LLVM Release Status Apr 3, 2025
@github-project-automation github-project-automation bot moved this from Needs Triage to Done in LLVM Release Status Apr 3, 2025
swift-ci pushed a commit to swiftlang/llvm-project that referenced this issue Apr 11, 2025
…lvm#133582)

PR llvm#91400 broke the usage of
HeaderFilterRegex via config file, because it is now created at a
different point in the execution and leads to a different value.

The result of that is that using HeaderFilterRegex only in the config
file does NOT work, in other words clang-tidy stops triggering warnings
on header files, thereby losing a lot of coverage.

This patch reverts the logic so that the header filter is created upon
calling the getHeaderFilter() function.

Additionally, this patch adds 2 unit tests to prevent regressions in the
future:

- One of them, "simple", tests the most basic use case with a single
top-level .clang-tidy file.

- The second one, "inheritance", demonstrates that the subfolder only
gets warnings from headers within it, and not from parent headers.

Fixes llvm#118009
Fixes llvm#121969
Fixes llvm#133453

Co-authored-by: Carlos Gálvez <[email protected]>
(cherry picked from commit 6333fa5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.

4 participants