Skip to content

Fix #15081 (usability: try to report misuse of exclude options) - #8906

Open
danmar wants to merge 1 commit into
cppcheck-opensource:mainfrom
cppchecksolutions:unused-exclude
Open

danmar wants to merge 1 commit into
cppcheck-opensource:mainfrom
cppchecksolutions:unused-exclude

Conversation

@danmar

@danmar danmar commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI balanced review requested due to automatic review settings September 30, 2026 19:57

This comment was marked as outdated.

Copilot AI balanced review requested due to automatic review settings September 30, 2026 20:01

This comment was marked as outdated.

@danmar
danmar marked this pull request as ready for review October 1, 2026 16:30
@danmar
danmar requested a balanced review from Copilot October 1, 2026 16:30

This comment was marked as outdated.

@danmar danmar changed the title Unused exclude Fix #15081 (usability: try to report misuse of exclude options) Oct 1, 2026
@danmar
danmar requested a balanced review from Copilot October 2, 2026 04:29

This comment was marked as outdated.

Comment thread cli/cmdlineparser.cpp
Comment thread lib/pathmatch.cpp
}
}

std::vector<std::string> PathMatch::unmatched() const {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI review take it with a grain of salt. Please feel free to reject it by clicking on Resolve button

Header excludes can never be "used", because Path::acceptFile() filters out headers before ignored.match() is called. So -iinc/h.h src or -i*.h src now prints:

cppcheck: filename exclusion does not apply to header (.h and .hpp) files.
cppcheck: Please use --suppress for ignoring results from the header files.
cppcheck: error: unused ignore/exclude path 'inc/h.h'. To hide warnings in certain files use suppressions instead.

and exits with code 1. Before, this was only an informational message. If failing is intended for headers, the first two lines could probably be merged into the error, or dropped, so the same thing isn't said twice. If it isn't intended, header patterns could be left out of the unused check.

@danmar

danmar commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@claude review

Comment thread lib/pathmatch.cpp
// paths inside a matched directory are not traversed, so a pattern that is
// covered by a matched pattern is considered used
const Filemode mode = !s.empty() && PathIterator::issep(s.back(), mSyntax) ? Filemode::directory : Filemode::regular;
return std::none_of(mMatchedPatterns.cbegin(), mMatchedPatterns.cend(), [&](const std::string& matched) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False negative: this "covered by a matched pattern" check runs against every matched pattern, but the reasoning only holds for patterns that matched a directory. Only directory matches stop the traversal. A file pattern never hides anything.

Examples where a stale pattern goes unreported:

  • -ifoo.cpp -inonexistent/foo.cpp: foo.cpp matches lib/foo.cpp, and match("foo.cpp", "nonexistent/foo.cpp") is true, so the second pattern counts as used.
  • -i*_test.cpp -imissing_test.cpp: the glob matches some file, so missing_test.cpp is never reported.

Suggestion: keep track of which patterns matched with Filemode::directory, and only use those for this check.

Comment thread cli/cmdlineparser.cpp

const auto& unmatched = matcher.unmatched();
if (!unmatched.empty()) {
mLogger.printError("unused ignore/exclude path '" + unmatched.front() + "'. To hide warnings in certain files use suppressions instead.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of points about making this a hard error:

  • Only unmatched.front() is reported. If a user has several stale -i paths, they have to fix one and re-run for each. Listing all of them would be easier to use (same for the project branch below).
  • -ifoo.h now always fails, because headers are never passed to match(). The user first sees the existing "filename exclusion does not apply to header files" info message and then this error. It may be worth making the two messages consistent.
  • Builds that share one ignore list across different path arguments will now fail. So will builds that ignore generated directories that don't exist yet, e.g. -ibuild/ on a fresh checkout. Is a hard error (rather than a warning) intended here? If so, the release note should call it out as a breaking change.

@claude

claude Bot commented Oct 7, 2026

Copy link
Copy Markdown

Overall the approach looks good: PathMatch records which patterns matched, and moving --file-filter out of importVcxproj means the filter no longer causes false "unused" reports. Points from the review:

  • False negative in PathMatch::unmatched() (inline): the "covered by a matched pattern" check should only use patterns that matched a directory. As written, an earlier match of foo.cpp or *_test.cpp hides stale patterns like nonexistent/foo.cpp or missing_test.cpp. A test such as PathMatch({"foo.cpp", "x/foo.cpp"}) that only matches lib/foo.cpp would catch this.
  • CLI (inline): only the first unused path is reported. -i<header> now always fails. Making this a hard error is a breaking change for scripts that share ignore lists or ignore directories that don't exist yet.
  • GUI inconsistency: MainWindow::doAnalyzeProject still throws away the return value of p.ignorePaths(v). So GUI projects that import a compile database, sln or vcxproj never report unused excludes, although the release note says the GUI now reports them.
  • Tests: there is no CLI/python test for an unused exclude coming from a .cppcheck project's excludedPaths, or for --file-filter with a vcxproj/sln now that filtering moved out of importVcxproj.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants