[clang-tools-extra] 8363b0a - [clang-tidy] add AllowedTypes option to misc-const-correctness (#122951)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 19 13:47:21 PST 2025
Author: Baranov Victor
Date: 2025-02-20T05:47:17+08:00
New Revision: 8363b0a6bab041b54316962e3e8948098148baeb
URL: https://github.com/llvm/llvm-project/commit/8363b0a6bab041b54316962e3e8948098148baeb
DIFF: https://github.com/llvm/llvm-project/commit/8363b0a6bab041b54316962e3e8948098148baeb.diff
LOG: [clang-tidy] add AllowedTypes option to misc-const-correctness (#122951)
Add option `AllowedTypes` which allow users to specify types they want
to exclude from const-correctness check.
Small real-world example:
```cpp
#include <mutex>
int main() {
std::mutex m;
std::lock_guard<std::mutex> l(m); // we want to ignore it since std::lock_guard is already immutable.
}
```
Closes issue https://github.com/llvm/llvm-project/issues/122592
Added:
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp
Modified:
clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
index 71a4cee4bdc6e..6e412e576e5f9 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -8,6 +8,8 @@
#include "ConstCorrectnessCheck.h"
#include "../utils/FixItHintUtils.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name,
TransformValues(Options.get("TransformValues", true)),
TransformReferences(Options.get("TransformReferences", true)),
TransformPointersAsValues(
- Options.get("TransformPointersAsValues", false)) {
+ Options.get("TransformPointersAsValues", false)),
+ AllowedTypes(
+ utils::options::parseStringList(Options.get("AllowedTypes", ""))) {
if (AnalyzeValues == false && AnalyzeReferences == false)
this->configurationDiag(
"The check 'misc-const-correctness' will not "
@@ -57,6 +61,8 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "TransformValues", TransformValues);
Options.store(Opts, "TransformReferences", TransformReferences);
Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues);
+ Options.store(Opts, "AllowedTypes",
+ utils::options::serializeStringList(AllowedTypes));
}
void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
@@ -73,6 +79,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType())))),
hasType(referenceType(pointee(substTemplateTypeParmType()))));
+ const auto AllowedType = hasType(qualType(anyOf(
+ hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
+ references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
+ pointerType(pointee(hasDeclaration(
+ namedDecl(matchers::matchesAnyListedName(AllowedTypes))))))));
+
const auto AutoTemplateType = varDecl(
anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType()))),
hasType(pointerType(pointee(autoType())))));
@@ -87,7 +99,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
unless(anyOf(ConstType, ConstReference, TemplateType,
hasInitializer(isInstantiationDependent()), AutoTemplateType,
RValueReference, FunctionPointerRef,
- hasType(cxxRecordDecl(isLambda())), isImplicit())));
+ hasType(cxxRecordDecl(isLambda())), isImplicit(),
+ AllowedType)));
// Match the function scope for which the analysis of all local variables
// shall be run.
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
index bba060e555d00..87dddc4faf781 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
@@ -45,6 +45,7 @@ class ConstCorrectnessCheck : public ClangTidyCheck {
const bool TransformValues;
const bool TransformReferences;
const bool TransformPointersAsValues;
+ const std::vector<StringRef> AllowedTypes;
};
} // namespace clang::tidy::misc
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6b8fe22242417..41ff1c1016f25 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -106,6 +106,11 @@ Changes in existing checks
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
additional C++ member functions to match.
+- Improved :doc:`misc-const-correctness
+ <clang-tidy/checks/misc/const-correctness>` check by adding the option
+ `AllowedTypes`, that excludes specified types from const-correctness
+ checking.
+
- Improved :doc:`misc-redundant-expression
<clang-tidy/checks/misc/redundant-expression>` check by providing additional
examples and fixing some macro related false positives.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
index 8ac1ad56bc8cf..2e7e0f3602ab9 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst
@@ -80,9 +80,10 @@ This limitation affects the capability to add ``const`` to methods which is not
Options
-------
-.. option:: AnalyzeValues (default = true)
+.. option:: AnalyzeValues
- Enable or disable the analysis of ordinary value variables, like ``int i = 42;``
+ Enable or disable the analysis of ordinary value variables, like
+ ``int i = 42;``. Default is `true`.
.. code-block:: c++
@@ -96,9 +97,10 @@ Options
// No warning
int const a[] = {42, 42, 42};
-.. option:: AnalyzeReferences (default = true)
+.. option:: AnalyzeReferences
- Enable or disable the analysis of reference variables, like ``int &ref = i;``
+ Enable or disable the analysis of reference variables, like
+ ``int &ref = i;``. Default is `true`.
.. code-block:: c++
@@ -108,11 +110,11 @@ Options
// No warning
int const& ref = i;
-.. option:: WarnPointersAsValues (default = false)
+.. option:: WarnPointersAsValues
This option enables the suggestion for ``const`` of the pointer itself.
Pointer values have two possibilities to be ``const``, the pointer
- and the value pointing to.
+ and the value pointing to. Default is `false`.
.. code-block:: c++
@@ -123,9 +125,10 @@ Options
// No warning
const int *const pointer_variable = &value;
-.. option:: TransformValues (default = true)
+.. option:: TransformValues
- Provides fixit-hints for value types that automatically add ``const`` if its a single declaration.
+ Provides fixit-hints for value types that automatically add ``const`` if
+ its a single declaration. Default is `true`.
.. code-block:: c++
@@ -143,10 +146,10 @@ Options
int result = value * 3;
result -= 10;
-.. option:: TransformReferences (default = true)
+.. option:: TransformReferences
- Provides fixit-hints for reference types that automatically add ``const`` if its a single
- declaration.
+ Provides fixit-hints for reference types that automatically add ``const`` if
+ its a single declaration. Default is `true`.
.. code-block:: c++
@@ -163,10 +166,10 @@ Options
int result = ref_value * 3;
result -= 10;
-.. option:: TransformPointersAsValues (default = false)
+.. option:: TransformPointersAsValues
- Provides fixit-hints for pointers if their pointee is not changed. This does not analyze if the
- value-pointed-to is unchanged!
+ Provides fixit-hints for pointers if their pointee is not changed. This does
+ not analyze if the value-pointed-to is unchanged! Default is `false`.
Requires 'WarnPointersAsValues' to be 'true'.
@@ -196,3 +199,13 @@ Options
// The following pointer may not become a 'int *const'.
int *changing_pointee = &value;
changing_pointee = &result;
+
+.. option:: AllowedTypes
+
+ A semicolon-separated list of names of types that will be excluded from
+ const-correctness checking. Regular expressions are accepted, e.g.
+ ``[Rr]ef(erence)?$`` matches every type with suffix ``Ref``, ``ref``,
+ ``Reference`` and ``reference``. If a name in the list contains the sequence
+ `::`, it is matched against the qualified type name
+ (i.e. ``namespace::Type``), otherwise it is matched against only the type
+ name (i.e. ``Type``). Default is empty string.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp
new file mode 100644
index 0000000000000..a73b4a08d0a71
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp
@@ -0,0 +1,180 @@
+// RUN: %check_clang_tidy %s misc-const-correctness %t -- \
+// RUN: -config="{CheckOptions: {\
+// RUN: misc-const-correctness.AllowedTypes: '[Pp]ointer$;[Pp]tr$;[Rr]ef(erence)?$;qualified::Type;::fully::QualifiedType;ConstTemplate', \
+// RUN: misc-const-correctness.TransformPointersAsValues: true, \
+// RUN: misc-const-correctness.TransformReferences: true, \
+// RUN: misc-const-correctness.WarnPointersAsValues: true } \
+// RUN: }" -- -fno-delayed-template-parsing
+
+struct SmartPointer {
+};
+
+struct smart_pointer {
+};
+
+struct SmartPtr {
+};
+
+struct smart_ptr {
+};
+
+struct SmartReference {
+};
+
+struct smart_reference {
+};
+
+struct SmartRef {
+};
+
+struct smart_ref {
+};
+
+struct OtherType {
+};
+
+template <typename T> struct ConstTemplate {
+};
+
+namespace qualified {
+struct Type {
+};
+} // namespace qualified
+
+namespace fully {
+struct QualifiedType {
+};
+} // namespace fully
+
+void negativeSmartPointer() {
+ SmartPointer p1 = {};
+ SmartPointer* p2 = {};
+ SmartPointer& p3 = p1;
+}
+
+void negative_smart_pointer() {
+ smart_pointer p1 = {};
+ smart_pointer* p2 = {};
+ smart_pointer& p3 = p1;
+}
+
+void negativeSmartPtr() {
+ SmartPtr p1 = {};
+ SmartPtr* p2 = {};
+ SmartPtr& p3 = p1;
+}
+
+void negative_smart_ptr() {
+ smart_ptr p1 = {};
+ smart_ptr* p2 = {};
+ smart_ptr& p3 = p1;
+}
+
+void negativeSmartReference() {
+ SmartReference p1 = {};
+ SmartReference* p2 = {};
+ SmartReference& p3 = p1;
+}
+
+void negative_smart_reference() {
+ smart_reference p1 = {};
+ smart_reference* p2 = {};
+ smart_reference& p3 = p1;
+}
+
+void negativeSmartRef() {
+ SmartRef p1 = {};
+ SmartRef* p2 = {};
+ SmartRef& p3 = p1;
+}
+
+void negative_smart_ref() {
+ smart_ref p1 = {};
+ smart_ref* p2 = {};
+ smart_ref& p3 = p1;
+}
+
+void positiveOtherType() {
+ OtherType t = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't' of type 'OtherType' can be declared 'const'
+ // CHECK-FIXES: OtherType const t = {};
+}
+
+void negativeSomeComplex() {
+ ConstTemplate<int> t1 = {};
+ ConstTemplate<int>* t2 = {};
+ ConstTemplate<int>& t3 = t1;
+}
+
+void negativeQualified() {
+ qualified::Type t1 = {};
+ qualified::Type* t2 = {};
+ qualified::Type& t3 = t1;
+
+ using qualified::Type;
+ Type t4 = {};
+ Type* t5 = {};
+ Type& t6 = t4;
+}
+
+void negativeFullyQualified() {
+ fully::QualifiedType t1 = {};
+ fully::QualifiedType* t2 = {};
+ fully::QualifiedType& t3 = t1;
+
+ using fully::QualifiedType;
+ QualifiedType t4 = {};
+ QualifiedType* t5 = {};
+ QualifiedType& t6 = t4;
+}
+
+using MySP = SmartPointer;
+using MyTemplate = ConstTemplate<int>;
+template <typename T> using MyTemplate2 = ConstTemplate<T>;
+
+void positiveTypedefs() {
+ MySP p1 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p1' of type 'MySP' (aka 'SmartPointer') can be declared 'const'
+ // CHECK-FIXES: MySP const p1 = {};
+
+ MySP* p2 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p2' of type 'MySP *' (aka 'SmartPointer *') can be declared 'const'
+ // CHECK-FIXES: MySP* const p2 = {};
+
+ MySP& p3 = p1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p3' of type 'MySP &' (aka 'SmartPointer &') can be declared 'const'
+ // CHECK-FIXES: MySP const& p3 = p1;
+
+ MyTemplate t1 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't1' of type 'MyTemplate' (aka 'ConstTemplate<int>') can be declared 'const'
+ // CHECK-FIXES: MyTemplate const t1 = {};
+
+ MyTemplate* t2 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't2' of type 'MyTemplate *' (aka 'ConstTemplate<int> *') can be declared 'const'
+ // CHECK-FIXES: MyTemplate* const t2 = {};
+
+ MyTemplate& t3 = t1;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't3' of type 'MyTemplate &' (aka 'ConstTemplate<int> &') can be declared 'const'
+ // CHECK-FIXES: MyTemplate const& t3 = t1;
+
+ MyTemplate2<int> t4 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't4' of type 'MyTemplate2<int>' (aka 'ConstTemplate<int>') can be declared 'const'
+ // CHECK-FIXES: MyTemplate2<int> const t4 = {};
+
+ MyTemplate2<int>* t5 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't5' of type 'MyTemplate2<int> *' (aka 'ConstTemplate<int> *') can be declared 'const'
+ // CHECK-FIXES: MyTemplate2<int>* const t5 = {};
+
+ MyTemplate2<int>& t6 = t4;
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 't6' of type 'MyTemplate2<int> &' (aka 'ConstTemplate<int> &') can be declared 'const'
+ // CHECK-FIXES: MyTemplate2<int> const& t6 = t4;
+}
+
+template <typename T>
+class Vector {};
+
+void positiveSmartPtrWrapped() {
+ Vector<SmartPtr> vec = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'vec' of type 'Vector<SmartPtr>' can be declared 'const'
+ // CHECK-FIXES: Vector<SmartPtr> const vec = {};
+}
More information about the cfe-commits
mailing list