Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d176aa3
Copied over everything
Jun 26, 2025
0931979
Respond to reviews: Specify auto type, add to release notes and check…
Jul 7, 2025
b61cfcc
Merge branch 'main' into readability-qualified-auto-opaque-types
JuanBesa Jul 7, 2025
9dfd9bb
Move the option logic into the Matcher
Jul 8, 2025
5d0a2f5
Merged release notes
Jul 8, 2025
fd43946
Extra space in release notes
Jul 8, 2025
acf71b5
Merge branch 'llvm:main' into readability-qualified-auto-opaque-types
JuanBesa Jul 14, 2025
ea71c1b
Merge branch 'llvm:main' into readability-qualified-auto-opaque-types
JuanBesa Jul 15, 2025
61bf13e
[llvm] Use llvm::fill (NFC) (#146988)
kazutakahirata Jul 4, 2025
0e287e0
Merge the tests
Jul 14, 2025
591e57f
Change the name to IgnoreAliasing
Jul 14, 2025
098cafa
Updated the documentation, added note about limitation
Jul 14, 2025
16eee24
Improved docs following reviewer comments
Jul 15, 2025
6c89510
Capture this instead
Jul 15, 2025
404dae6
Merge matcher and improve documentation
Jul 22, 2025
261d315
Update clang-tools-extra/docs/clang-tidy/checks/readability/qualified…
JuanBesa Jul 22, 2025
df7166a
Merge branch 'main' into readability-qualified-auto-opaque-types
JuanBesa Jul 22, 2025
5c8c137
Small line change
Jul 22, 2025
b4c03cf
pulled new version
Jul 22, 2025
2492808
Merge branch 'main' into readability-qualified-auto-opaque-types
JuanBesa Jul 22, 2025
62b7417
Update spacing clang-tools-extra/docs/clang-tidy/checks/readability/q…
JuanBesa Jul 24, 2025
db448e4
Merge branch 'main' into readability-qualified-auto-opaque-types
JuanBesa Jul 24, 2025
10ee733
Merge branch 'main' into readability-qualified-auto-opaque-types
JuanBesa Jul 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,14 @@ QualifiedAutoCheck::QualifiedAutoCheck(StringRef Name,
: ClangTidyCheck(Name, Context),
AddConstToQualified(Options.get("AddConstToQualified", true)),
AllowedTypes(
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
utils::options::parseStringList(Options.get("AllowedTypes", ""))),
IgnoreAliasing(Options.get("IgnoreAliasing", true)) {}

void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "AddConstToQualified", AddConstToQualified);
Options.store(Opts, "AllowedTypes",
utils::options::serializeStringList(AllowedTypes));
Options.store(Opts, "IgnoreAliasing", IgnoreAliasing);
}

void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
Expand All @@ -134,14 +136,26 @@ void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {

auto IsBoundToType = refersToType(equalsBoundNode("type"));
auto UnlessFunctionType = unless(hasUnqualifiedDesugaredType(functionType()));
auto IsAutoDeducedToPointer = [](const std::vector<StringRef> &AllowedTypes,
const auto &...InnerMatchers) {
return autoType(hasDeducedType(
hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...))),
unless(hasUnqualifiedType(
matchers::matchesAnyListedTypeName(AllowedTypes, false))),
unless(pointerType(pointee(hasUnqualifiedType(
matchers::matchesAnyListedTypeName(AllowedTypes, false)))))));
auto IsAutoDeducedToPointer = [this](
const std::vector<StringRef> &AllowedTypes,
const auto &...InnerMatchers) {
if (this->IgnoreAliasing) {
return autoType(hasDeducedType(
hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...))),
unless(hasUnqualifiedType(
matchers::matchesAnyListedTypeName(AllowedTypes, false))),
unless(pointerType(pointee(hasUnqualifiedType(
matchers::matchesAnyListedTypeName(AllowedTypes, false)))))));
} else {
return autoType(hasDeducedType(
anyOf(qualType(pointerType(pointee(InnerMatchers...))),
qualType(substTemplateTypeParmType(hasReplacementType(
pointerType(pointee(InnerMatchers...)))))),
unless(hasUnqualifiedType(
matchers::matchesAnyListedTypeName(AllowedTypes, false))),
unless(pointerType(pointee(hasUnqualifiedType(
matchers::matchesAnyListedTypeName(AllowedTypes, false)))))));
}
};

Finder->addMatcher(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class QualifiedAutoCheck : public ClangTidyCheck {
private:
const bool AddConstToQualified;
const std::vector<StringRef> AllowedTypes;
const bool IgnoreAliasing;
};

} // namespace clang::tidy::readability
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ Changes in existing checks
- Improved :doc:`readability-qualified-auto
<clang-tidy/checks/readability/qualified-auto>` check by adding the option
`AllowedTypes`, that excludes specified types from adding qualifiers.
Added the option `IgnoreAliasing`, that allows not looking at underlying
types of type aliases.

- Improved :doc:`readability-redundant-inline-specifier
<clang-tidy/checks/readability/redundant-inline-specifier>` check by fixing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,49 @@ Note in the LLVM alias, the default value is `false`.
matched against only the type name (i.e. ``Type``). E.g. to suppress reports
for ``std::array`` iterators use `std::array<.*>::(const_)?iterator` string.
The default is an empty string.

.. option:: IgnoreAliasing

If set to `true` the check will use the underlying type to determine the type
that ``auto`` is deduced to.
If set to `false` the check will not look beyond the first type alias.
Default value is `true`.

.. code-block:: c++

using IntPtr = int*;
IntPtr foo();

auto bar = foo();

If :option:`IgnoreAliasing` is set to `true`, it will be transformed into:

.. code-block:: c++

auto *bar = foo();

Otherwise no changes will occur.

Limitations
-----------

When :option:`IgnoreAliasing` is set to `false`, there are cases where
Clang has not preserved the type alias and the underlying type will be used so
false positives may occur.
For example:

.. code-block:: c++

#include <vector>

void change(int&);

using IntPtr = int *; // Relevant typedef

void loopPtr(const std::vector<IntPtr> &VectorIntPtr) {

// May fail for IgnoreAliasing==false as AST does not have the IntPtr
for (auto Data : VectorIntPtr) {
change(*Data);
}
}
Loading