[clang-tools-extra] r272025 - Add the misc-misplaced-const check to clang-tidy, which diagnoses when a const-qualifier is applied to a typedef of pointer type rather than to the pointee type.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 7 10:22:47 PDT 2016


Author: aaronballman
Date: Tue Jun  7 12:22:47 2016
New Revision: 272025

URL: http://llvm.org/viewvc/llvm-project?rev=272025&view=rev
Log:
Add the misc-misplaced-const check to clang-tidy, which diagnoses when a const-qualifier is applied to a typedef of pointer type rather than to the pointee type.

Added:
    clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/misc-misplaced-const.rst
    clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.c
    clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=272025&r1=272024&r2=272025&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Tue Jun  7 12:22:47 2016
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyMiscModule
   ArgumentCommentCheck.cpp
   AssertSideEffectCheck.cpp
+  MisplacedConstCheck.cpp
   UnconventionalAssignOperatorCheck.cpp
   BoolPointerImplicitConversionCheck.cpp
   DanglingHandleCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=272025&r1=272024&r2=272025&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Tue Jun  7 12:22:47 2016
@@ -12,6 +12,7 @@
 #include "../ClangTidyModuleRegistry.h"
 #include "ArgumentCommentCheck.h"
 #include "AssertSideEffectCheck.h"
+#include "MisplacedConstCheck.h"
 #include "UnconventionalAssignOperatorCheck.h"
 #include "BoolPointerImplicitConversionCheck.h"
 #include "DanglingHandleCheck.h"
@@ -61,6 +62,8 @@ public:
     CheckFactories.registerCheck<ArgumentCommentCheck>("misc-argument-comment");
     CheckFactories.registerCheck<AssertSideEffectCheck>(
         "misc-assert-side-effect");
+    CheckFactories.registerCheck<MisplacedConstCheck>(
+        "misc-misplaced-const");
     CheckFactories.registerCheck<UnconventionalAssignOperatorCheck>(
         "misc-unconventional-assign-operator");
     CheckFactories.registerCheck<BoolPointerImplicitConversionCheck>(

Added: clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.cpp?rev=272025&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.cpp Tue Jun  7 12:22:47 2016
@@ -0,0 +1,63 @@
+//===--- MisplacedConstCheck.cpp - clang-tidy------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MisplacedConstCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+void MisplacedConstCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      valueDecl(hasType(isConstQualified()),
+                hasType(typedefType(hasDeclaration(
+                    typedefDecl(hasType(pointerType(unless(pointee(
+                                    anyOf(isConstQualified(),
+                                          ignoringParens(functionType())))))))
+                        .bind("typedef")))))
+          .bind("decl"),
+      this);
+}
+
+static QualType guessAlternateQualification(ASTContext &Context, QualType QT) {
+  // We're given a QualType from a typedef where the qualifiers apply to the
+  // pointer instead of the pointee. Strip the const qualifier from the pointer
+  // type and add it to the pointee instead.
+  if (!QT->isPointerType())
+    return QT;
+
+  Qualifiers Quals = QT.getLocalQualifiers();
+  Quals.removeConst();
+
+  QualType NewQT = Context.getPointerType(
+      QualType(QT->getPointeeType().getTypePtr(), Qualifiers::Const));
+  return NewQT.withCVRQualifiers(Quals.getCVRQualifiers());
+}
+
+void MisplacedConstCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Var = Result.Nodes.getNodeAs<ValueDecl>("decl");
+  const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>("typedef");
+  ASTContext &Ctx = *Result.Context;
+  QualType CanQT = Var->getType().getCanonicalType();
+
+  diag(Var->getLocation(), "%0 declared with a const-qualified typedef type; "
+                           "results in the type being '%1' instead of '%2'")
+      << Var << CanQT.getAsString(Ctx.getPrintingPolicy())
+      << guessAlternateQualification(Ctx, CanQT)
+             .getAsString(Ctx.getPrintingPolicy());
+  diag(Typedef->getLocation(), "typedef declared here", DiagnosticIDs::Note);
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.h?rev=272025&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/MisplacedConstCheck.h Tue Jun  7 12:22:47 2016
@@ -0,0 +1,36 @@
+//===--- MisplacedConstCheck.h - clang-tidy----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISPLACED_CONST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISPLACED_CONST_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// This check diagnoses when a const qualifier is applied to a typedef to a
+/// pointer type rather than to the pointee.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-misplaced-const.html
+class MisplacedConstCheck : public ClangTidyCheck {
+public:
+  MisplacedConstCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISPLACED_CONST_H

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=272025&r1=272024&r2=272025&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Tue Jun  7 12:22:47 2016
@@ -4,7 +4,6 @@ Clang-Tidy Checks
 =========================
 
 .. toctree::
-
    boost-use-to-string
    cert-dcl03-c (redirects to misc-static-assert) <cert-dcl03-c>
    cert-dcl50-cpp
@@ -63,6 +62,7 @@ Clang-Tidy Checks
    misc-inefficient-algorithm
    misc-macro-parentheses
    misc-macro-repeated-side-effects
+   misc-misplaced-const
    misc-misplaced-widening-cast
    misc-move-const-arg
    misc-move-constructor-init

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/misc-misplaced-const.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/misc-misplaced-const.rst?rev=272025&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/misc-misplaced-const.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/misc-misplaced-const.rst Tue Jun  7 12:22:47 2016
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - misc-misplaced-const
+
+misc-misplaced-const
+====================
+
+This check diagnoses when a const qualifier is applied to a typedef to a pointer
+type rather than to the pointee, because such constructs are often misleading to
+developers because the const applies to the pointer rather than the pointee.
+
+For instance, in the following code, the resulting type is `int *` const rather
+than `const int *`:
+
+.. code:: c++
+
+  typedef int *int_ptr;
+  void f(const int_ptr ptr);
+
+The check does not diagnose when the underlying typedef type is a pointer to a
+const type or a function pointer type. This is because the const qualifier is
+less likely to be mistaken because it would be redundant (or disallowed) on the
+underlying pointee type.

Added: clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.c?rev=272025&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.c Tue Jun  7 12:22:47 2016
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s misc-misplaced-const %t
+
+typedef int plain_i;
+typedef int *ip;
+typedef const int *cip;
+
+typedef void (*func_ptr)(void);
+
+void func(void) {
+  // ok
+  const int *i0 = 0;
+  const plain_i *i1 = 0;
+  const cip i2 = 0; // const applies to both pointer and pointee.
+
+  // Not ok
+  const ip i3 = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i3' declared with a const-qualified typedef type; results in the type being 'int *const' instead of 'const int *'
+
+  ip const i4 = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i4' declared with a const-qualified
+
+  const volatile ip i5 = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'i5' declared with a const-qualified typedef type; results in the type being 'int *const volatile' instead of 'const int *volatile'
+}
+
+void func2(const plain_i *i1,
+           const cip i2,
+           const ip i3,
+           // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'i3' declared with a const-qualified
+           const int *i4) {
+}
+
+struct S {
+  const int *i0;
+  const plain_i *i1;
+  const cip i2;
+  const ip i3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i3' declared with a const-qualified
+};
+
+// Function pointers should not be diagnosed because a function
+// pointer type can never be const.
+void func3(const func_ptr fp) {
+  const func_ptr fp2 = fp;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.cpp?rev=272025&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-misplaced-const.cpp Tue Jun  7 12:22:47 2016
@@ -0,0 +1,37 @@
+// RUN: %check_clang_tidy %s misc-misplaced-const %t
+
+typedef int plain_i;
+typedef int *ip;
+typedef const int *cip;
+
+void func() {
+  if (const int *i = 0)
+    ;
+  if (const plain_i *i = 0)
+    ;
+  if (const cip i = 0)
+    ;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: 'i' declared with a const-qualified typedef type; results in the type being 'int *const' instead of 'const int *'
+  if (const ip i = 0)
+    ;
+}
+
+template <typename Ty>
+struct S {
+  const Ty *i;
+  const Ty &i2;
+};
+
+template struct S<int>;
+template struct S<ip>; // ok
+template struct S<cip>;
+template struct S<int *>; // ok
+
+struct T {
+  typedef void (T::*PMF)();
+
+  void f() {
+    const PMF val = &T::f; // ok
+  }
+};




More information about the cfe-commits mailing list