[clang-tools-extra] [clang-tidy] Improved cppcoreguidelines-pro-type-const-cast (PR #69501)

Piotr Zegar via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 11:39:12 PDT 2023


https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/69501

>From ada6ee07f310ce482ef0cb0339b25db6e31d8c13 Mon Sep 17 00:00:00 2001
From: Piotr Zegar <me at piotrzegar.pl>
Date: Wed, 18 Oct 2023 19:10:32 +0000
Subject: [PATCH 1/3] [clang-tidy] Improved
 cppcoreguidelines-pro-type-const-cast

Improved cppcoreguidelines-pro-type-const-cast check to ignore
casts to const type (controlled by  option) and casts in
implicitly invoked code.
---
 .../ProTypeConstCastCheck.cpp                 | 33 +++++++++++++++++--
 .../cppcoreguidelines/ProTypeConstCastCheck.h | 12 +++++--
 clang-tools-extra/docs/ReleaseNotes.rst       |  5 +++
 .../cppcoreguidelines/pro-type-const-cast.rst | 24 +++++++++++---
 .../cppcoreguidelines/pro-type-const-cast.cpp | 28 ++++++++++++++--
 .../nonstandard-file-extension.test           |  2 +-
 6 files changed, 91 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
index ef803ab85fa0841..4661c7d072f9256 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
@@ -14,13 +14,42 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::cppcoreguidelines {
 
+static bool hasConstQualifier(QualType Type) {
+  const QualType PtrType = Type->getPointeeType();
+  if (!PtrType.isNull())
+    return hasConstQualifier(PtrType);
+
+  return Type.isConstQualified();
+}
+
+namespace {
+AST_MATCHER(QualType, hasConst) { return hasConstQualifier(Node); }
+} // namespace
+
+ProTypeConstCastCheck::ProTypeConstCastCheck(StringRef Name,
+                                             ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      StrictMode(Options.getLocalOrGlobal("StrictMode", false)) {}
+
+void ProTypeConstCastCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "StrictMode", StrictMode);
+}
+
 void ProTypeConstCastCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(cxxConstCastExpr().bind("cast"), this);
+  if (StrictMode)
+    Finder->addMatcher(cxxConstCastExpr().bind("cast"), this);
+  else
+    Finder->addMatcher(cxxConstCastExpr(unless(hasDestinationType(
+                                            hasCanonicalType(hasConst()))))
+                           .bind("cast"),
+                       this);
 }
 
 void ProTypeConstCastCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *MatchedCast = Result.Nodes.getNodeAs<CXXConstCastExpr>("cast");
-  diag(MatchedCast->getOperatorLoc(), "do not use const_cast");
+  diag(MatchedCast->getOperatorLoc(),
+       "do not use const_cast%select{ to cast away const|}0")
+      << StrictMode;
 }
 
 } // namespace clang::tidy::cppcoreguidelines
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
index f7ae9bbb60dcda3..8d93633a321b53f 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
@@ -13,19 +13,25 @@
 
 namespace clang::tidy::cppcoreguidelines {
 
-/// This check flags all instances of const_cast
+/// Imposes limitations on the use of const_cast within C++ code.
 ///
 /// For the user-facing documentation see:
 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.html
 class ProTypeConstCastCheck : public ClangTidyCheck {
 public:
-  ProTypeConstCastCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+  ProTypeConstCastCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus;
   }
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  std::optional<TraversalKind> getCheckTraversalKind() const override {
+    return TK_IgnoreUnlessSpelledInSource;
+  }
+
+private:
+  const bool StrictMode;
 };
 
 } // namespace clang::tidy::cppcoreguidelines
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 3e1fbe091c9ff6a..0a9f6691ff68516 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -236,6 +236,11 @@ Changes in existing checks
   <clang-tidy/checks/cppcoreguidelines/pro-bounds-constant-array-index>` check
   to perform checks on derived classes of  ``std::array``.
 
+- Improved :doc:`cppcoreguidelines-pro-type-const-cast
+  <clang-tidy/checks/cppcoreguidelines/pro-type-const-cast>` check to ignore
+  casts to ``const`` type (controlled by `StrictMode` option) and casts in
+  implicitly invoked code.
+
 - Improved :doc:`cppcoreguidelines-pro-type-member-init
   <clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check to ignore
   dependent delegate constructors.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst
index eb572e625f12977..6db8f6a2efd3535 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst
@@ -3,11 +3,27 @@
 cppcoreguidelines-pro-type-const-cast
 =====================================
 
-This check flags all uses of ``const_cast`` in C++ code.
+Imposes limitations on the use of ``const_cast`` within C++ code. It depends on
+the :option:`StrictMode` option setting to determine whether it should flag all
+instances of ``const_cast`` or only those that remove the ``const`` qualifier.
 
-Modifying a variable that was declared const is undefined behavior, even with
-``const_cast``.
+Modifying a variable that has been declared as ``const`` in C++ is generally
+considered undefined behavior, and this remains true even when using
+``const_cast``. In C++, the ``const`` qualifier indicates that a variable is
+intended to be read-only, and the compiler enforces this by disallowing any
+attempts to change the value of that variable.
 
 This rule is part of the `Type safety (Type 3)
 <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Pro-type-constcast>`_
-profile from the C++ Core Guidelines.
+profile and `ES.50: Don’t cast away const
+<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es50-dont-cast-away-const>`_
+rule from the C++ Core Guidelines.
+
+Options
+-------
+
+.. option:: StrictMode
+
+  When this setting is set to `true`, it means that any usage of ``const_cast``
+  is not allowed. On the other hand, when it's set to `false`, it permits
+  casting to ``const`` types. By default, this setting is `false`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
index 2d32e13723abf83..8f48082b6274fce 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
@@ -1,6 +1,28 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-const-cast %t
+// RUN: %check_clang_tidy -check-suffix=STRICT  %s cppcoreguidelines-pro-type-const-cast %t -- -config="{CheckOptions: {StrictMode: true}}"
+// RUN: %check_clang_tidy -check-suffix=NSTRICT %s cppcoreguidelines-pro-type-const-cast %t
 
 const int *i;
 int *j;
-void f() { j = const_cast<int *>(i); }
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+void f() {
+  j = const_cast<int *>(i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:7: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = const_cast<const int*>(j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  j = *const_cast<int **>(&i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = *const_cast<const int**>(&j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  j = &const_cast<int&>(*i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = &const_cast<const int&>(*j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+}
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test b/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test
index 4cb4d1171195a01..e6d81cf304bb77a 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test
@@ -3,4 +3,4 @@
 const int *i;
 int *j;
 void f() { j = const_cast<int *>(i); }
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]

>From 045b354fd5a2a59d79d19f5638c7157f51094e4f Mon Sep 17 00:00:00 2001
From: Piotr Zegar <me at piotrzegar.pl>
Date: Wed, 25 Oct 2023 17:32:35 +0000
Subject: [PATCH 2/3] Change diagnostic message

---
 .../clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp  | 2 +-
 .../checkers/cppcoreguidelines/pro-type-const-cast.cpp      | 6 +++---
 .../infrastructure/nonstandard-file-extension.test          | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
index 4661c7d072f9256..ebafd9186342f40 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
@@ -48,7 +48,7 @@ void ProTypeConstCastCheck::registerMatchers(MatchFinder *Finder) {
 void ProTypeConstCastCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *MatchedCast = Result.Nodes.getNodeAs<CXXConstCastExpr>("cast");
   diag(MatchedCast->getOperatorLoc(),
-       "do not use const_cast%select{ to cast away const|}0")
+       "do not use const_cast%select{ to remove const qualifier|}0")
       << StrictMode;
 }
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
index 8f48082b6274fce..618894f2cb3c356 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
@@ -6,21 +6,21 @@ int *j;
 
 void f() {
   j = const_cast<int *>(i);
-  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:7: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:7: warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]
   // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
 
   i = const_cast<const int*>(j);
   // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
 
   j = *const_cast<int **>(&i);
-  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]
   // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
 
   i = *const_cast<const int**>(&j);
   // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
 
   j = &const_cast<int&>(*i);
-  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]
   // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
 
   i = &const_cast<const int&>(*j);
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test b/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test
index e6d81cf304bb77a..9f98d86d0bcc0f1 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/nonstandard-file-extension.test
@@ -3,4 +3,4 @@
 const int *i;
 int *j;
 void f() { j = const_cast<int *>(i); }
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast to cast away const [cppcoreguidelines-pro-type-const-cast]
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast to remove const qualifier [cppcoreguidelines-pro-type-const-cast]

>From 8e1bf994988c25a95d604812d0d984c17fa128a6 Mon Sep 17 00:00:00 2001
From: Piotr Zegar <me at piotrzegar.pl>
Date: Wed, 25 Oct 2023 18:37:30 +0000
Subject: [PATCH 3/3] Support volatile keyword

---
 .../ProTypeConstCastCheck.cpp                 | 42 ++++++++++----
 clang-tools-extra/docs/ReleaseNotes.rst       |  4 +-
 .../cppcoreguidelines/pro-type-const-cast.rst | 12 +++-
 .../cppcoreguidelines/pro-type-const-cast.cpp | 58 +++++++++++++++++++
 4 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
index ebafd9186342f40..8c44c1bfb62b6c7 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
@@ -22,9 +22,12 @@ static bool hasConstQualifier(QualType Type) {
   return Type.isConstQualified();
 }
 
-namespace {
-AST_MATCHER(QualType, hasConst) { return hasConstQualifier(Node); }
-} // namespace
+static bool hasVolatileQualifier(QualType Type) {
+  const QualType PtrType = Type->getPointeeType();
+  if (!PtrType.isNull())
+    return hasVolatileQualifier(PtrType);
+  return Type.isVolatileQualified();
+}
 
 ProTypeConstCastCheck::ProTypeConstCastCheck(StringRef Name,
                                              ClangTidyContext *Context)
@@ -36,20 +39,35 @@ void ProTypeConstCastCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 }
 
 void ProTypeConstCastCheck::registerMatchers(MatchFinder *Finder) {
-  if (StrictMode)
-    Finder->addMatcher(cxxConstCastExpr().bind("cast"), this);
-  else
-    Finder->addMatcher(cxxConstCastExpr(unless(hasDestinationType(
-                                            hasCanonicalType(hasConst()))))
-                           .bind("cast"),
-                       this);
+  Finder->addMatcher(cxxConstCastExpr().bind("cast"), this);
 }
 
 void ProTypeConstCastCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *MatchedCast = Result.Nodes.getNodeAs<CXXConstCastExpr>("cast");
+  if (StrictMode) {
+    diag(MatchedCast->getOperatorLoc(), "do not use const_cast");
+    return;
+  }
+
+  const QualType TargetType = MatchedCast->getType().getCanonicalType();
+  const QualType SourceType =
+      MatchedCast->getSubExpr()->getType().getCanonicalType();
+
+  const bool RemovingConst =
+      hasConstQualifier(SourceType) && !hasConstQualifier(TargetType);
+  const bool RemovingVolatile =
+      hasVolatileQualifier(SourceType) && !hasVolatileQualifier(TargetType);
+
+  if (!RemovingConst && !RemovingVolatile) {
+    // Cast is doing nothing.
+    return;
+  }
+
   diag(MatchedCast->getOperatorLoc(),
-       "do not use const_cast%select{ to remove const qualifier|}0")
-      << StrictMode;
+       "do not use const_cast to remove%select{| const}0%select{| "
+       "and}2%select{| volatile}1 qualifier")
+      << RemovingConst << RemovingVolatile
+      << (RemovingConst && RemovingVolatile);
 }
 
 } // namespace clang::tidy::cppcoreguidelines
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 0a9f6691ff68516..095b94b589aabde 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -238,8 +238,8 @@ Changes in existing checks
 
 - Improved :doc:`cppcoreguidelines-pro-type-const-cast
   <clang-tidy/checks/cppcoreguidelines/pro-type-const-cast>` check to ignore
-  casts to ``const`` type (controlled by `StrictMode` option) and casts in
-  implicitly invoked code.
+  casts to ``const`` or ``volatile`` type (controlled by `StrictMode` option)
+  and casts in implicitly invoked code.
 
 - Improved :doc:`cppcoreguidelines-pro-type-member-init
   <clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check to ignore
diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst
index 6db8f6a2efd3535..961a591cb81f868 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-const-cast.rst
@@ -5,7 +5,8 @@ cppcoreguidelines-pro-type-const-cast
 
 Imposes limitations on the use of ``const_cast`` within C++ code. It depends on
 the :option:`StrictMode` option setting to determine whether it should flag all
-instances of ``const_cast`` or only those that remove the ``const`` qualifier.
+instances of ``const_cast`` or only those that remove either ``const`` or
+``volatile`` qualifier.
 
 Modifying a variable that has been declared as ``const`` in C++ is generally
 considered undefined behavior, and this remains true even when using
@@ -13,6 +14,13 @@ considered undefined behavior, and this remains true even when using
 intended to be read-only, and the compiler enforces this by disallowing any
 attempts to change the value of that variable.
 
+Removing the ``volatile`` qualifier in C++ can have serious consequences. This
+qualifier indicates that a variable's value can change unpredictably, and
+removing it may lead to undefined behavior, optimization problems, and debugging
+challenges. It's essential to retain the ``volatile`` qualifier in situations
+where the variable's volatility is a crucial aspect of program correctness and
+reliability.
+
 This rule is part of the `Type safety (Type 3)
 <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Pro-type-constcast>`_
 profile and `ES.50: Don’t cast away const
@@ -26,4 +34,4 @@ Options
 
   When this setting is set to `true`, it means that any usage of ``const_cast``
   is not allowed. On the other hand, when it's set to `false`, it permits
-  casting to ``const`` types. By default, this setting is `false`.
+  casting to ``const`` or ``volatile`` types. Default value is `false`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
index 618894f2cb3c356..be70e3ba356991a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-const-cast.cpp
@@ -1,6 +1,7 @@
 // RUN: %check_clang_tidy -check-suffix=STRICT  %s cppcoreguidelines-pro-type-const-cast %t -- -config="{CheckOptions: {StrictMode: true}}"
 // RUN: %check_clang_tidy -check-suffix=NSTRICT %s cppcoreguidelines-pro-type-const-cast %t
 
+namespace Const {
 const int *i;
 int *j;
 
@@ -26,3 +27,60 @@ void f() {
   i = &const_cast<const int&>(*j);
   // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
 }
+}
+
+namespace Volatile {
+volatile int *i;
+int *j;
+
+void f() {
+  j = const_cast<int *>(i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:7: warning: do not use const_cast to remove volatile qualifier [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = const_cast<volatile int*>(j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  j = *const_cast<int **>(&i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to remove volatile qualifier [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = *const_cast<volatile int**>(&j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  j = &const_cast<int&>(*i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to remove volatile qualifier [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = &const_cast<volatile int&>(*j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+}
+}
+
+namespace ConstAndVolatile {
+const volatile int *i;
+int *j;
+
+void f() {
+  j = const_cast<int *>(i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:7: warning: do not use const_cast to remove const and volatile qualifier [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = const_cast<const volatile int*>(j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:7: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  j = *const_cast<int **>(&i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to remove const and volatile qualifier [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = *const_cast<const volatile int**>(&j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  j = &const_cast<int&>(*i);
+  // CHECK-MESSAGES-NSTRICT: :[[@LINE-1]]:8: warning: do not use const_cast to remove const and volatile qualifier [cppcoreguidelines-pro-type-const-cast]
+  // CHECK-MESSAGES-STRICT:  :[[@LINE-2]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+
+  i = &const_cast<const volatile int&>(*j);
+  // CHECK-MESSAGES-STRICT: :[[@LINE-1]]:8: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
+}
+}



More information about the cfe-commits mailing list