Skip to content

Commit 4d259de

Browse files
JuanBesajuanbesakazutakahirataEugeneZelenkovbvictor
authored
[clang-tidy] Add IgnoreAliasing option to readability-qualified-auto check (#147060)
`readability-qualified-auto` check currently looks at the unsugared type, skipping any typedefs, to determine if the variable is a pointer-type. This may not be the desired behaviour, in particular when the type depends on compilation flags. For example ``` #if CONDITION using Handler = int *; #else using Handler = uint64_t; #endif ``` A more common example is some implementations of `std::array` use pointers as iterators. This introduces the IgnoreAliasing option so that `readability-qualified-auto` does not look beyond typedefs. --------- Co-authored-by: juanbesa <[email protected]> Co-authored-by: Kazu Hirata <[email protected]> Co-authored-by: EugeneZelenko <[email protected]> Co-authored-by: Baranov Victor <[email protected]>
1 parent 5f2092d commit 4d259de

File tree

5 files changed

+155
-9
lines changed

5 files changed

+155
-9
lines changed

clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,14 @@ QualifiedAutoCheck::QualifiedAutoCheck(StringRef Name,
106106
: ClangTidyCheck(Name, Context),
107107
AddConstToQualified(Options.get("AddConstToQualified", true)),
108108
AllowedTypes(
109-
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
109+
utils::options::parseStringList(Options.get("AllowedTypes", ""))),
110+
IgnoreAliasing(Options.get("IgnoreAliasing", true)) {}
110111

111112
void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
112113
Options.store(Opts, "AddConstToQualified", AddConstToQualified);
113114
Options.store(Opts, "AllowedTypes",
114115
utils::options::serializeStringList(AllowedTypes));
116+
Options.store(Opts, "IgnoreAliasing", IgnoreAliasing);
115117
}
116118

117119
void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
@@ -134,16 +136,30 @@ void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
134136

135137
auto IsBoundToType = refersToType(equalsBoundNode("type"));
136138
auto UnlessFunctionType = unless(hasUnqualifiedDesugaredType(functionType()));
137-
auto IsAutoDeducedToPointer = [](const std::vector<StringRef> &AllowedTypes,
138-
const auto &...InnerMatchers) {
139-
return autoType(hasDeducedType(
140-
hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...))),
141-
unless(hasUnqualifiedType(
142-
matchers::matchesAnyListedTypeName(AllowedTypes, false))),
143-
unless(pointerType(pointee(hasUnqualifiedType(
144-
matchers::matchesAnyListedTypeName(AllowedTypes, false)))))));
139+
140+
auto IsPointerType = [this](const auto &...InnerMatchers) {
141+
if (this->IgnoreAliasing) {
142+
return qualType(
143+
hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...))));
144+
} else {
145+
return qualType(
146+
anyOf(qualType(pointerType(pointee(InnerMatchers...))),
147+
qualType(substTemplateTypeParmType(hasReplacementType(
148+
pointerType(pointee(InnerMatchers...)))))));
149+
}
145150
};
146151

152+
auto IsAutoDeducedToPointer =
153+
[IsPointerType](const std::vector<StringRef> &AllowedTypes,
154+
const auto &...InnerMatchers) {
155+
return autoType(hasDeducedType(
156+
IsPointerType(InnerMatchers...),
157+
unless(hasUnqualifiedType(
158+
matchers::matchesAnyListedTypeName(AllowedTypes, false))),
159+
unless(pointerType(pointee(hasUnqualifiedType(
160+
matchers::matchesAnyListedTypeName(AllowedTypes, false)))))));
161+
};
162+
147163
Finder->addMatcher(
148164
ExplicitSingleVarDecl(
149165
hasType(IsAutoDeducedToPointer(AllowedTypes, UnlessFunctionType)),

clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class QualifiedAutoCheck : public ClangTidyCheck {
3232
private:
3333
const bool AddConstToQualified;
3434
const std::vector<StringRef> AllowedTypes;
35+
const bool IgnoreAliasing;
3536
};
3637

3738
} // namespace clang::tidy::readability

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ Changes in existing checks
154154
<clang-tidy/checks/portability/template-virtual-member-function>` check to
155155
avoid false positives on pure virtual member functions.
156156

157+
- Improved :doc:`readability-qualified-auto
158+
<clang-tidy/checks/readability/qualified-auto>` check by adding the option
159+
`IgnoreAliasing`, that allows not looking at underlying types of type aliases.
160+
157161
Removed checks
158162
^^^^^^^^^^^^^^
159163

clang-tools-extra/docs/clang-tidy/checks/readability/qualified-auto.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,45 @@ Note in the LLVM alias, the default value is `false`.
9696
matched against only the type name (i.e. ``Type``). E.g. to suppress reports
9797
for ``std::array`` iterators use `std::array<.*>::(const_)?iterator` string.
9898
The default is an empty string.
99+
100+
.. option:: IgnoreAliasing
101+
102+
If set to `true` the check will use the underlying type to determine the type
103+
that ``auto`` is deduced to. If set to `false` the check will not look beyond
104+
the first type alias.
105+
Default value is `true`.
106+
107+
.. code-block:: c++
108+
109+
using IntPtr = int*;
110+
IntPtr foo();
111+
112+
auto bar = foo();
113+
114+
If :option:`IgnoreAliasing` is set to `true`, it will be transformed into:
115+
116+
.. code-block:: c++
117+
118+
auto *bar = foo();
119+
120+
Otherwise no changes will occur.
121+
122+
Limitations
123+
-----------
124+
125+
When :option:`IgnoreAliasing` is set to `false`, there are cases where
126+
Clang has not preserved the type alias and the underlying type will be used so
127+
false positives may occur.
128+
129+
For example:
130+
131+
.. code-block:: c++
132+
133+
using IntPtr = int *;
134+
135+
void loopPtr(const std::vector<IntPtr> &VectorIntPtr) {
136+
137+
// May fail for IgnoreAliasing==false as AST does not have the 'IntPtr'
138+
for (auto Data : VectorIntPtr) {
139+
}
140+
}

0 commit comments

Comments
 (0)