[clang-tools-extra] r302637 - [clang-tidy] Add new cert-dcl21-cpp check
Gabor Horvath via cfe-commits
cfe-commits at lists.llvm.org
Wed May 10 04:16:55 PDT 2017
Author: xazax
Date: Wed May 10 06:16:55 2017
New Revision: 302637
URL: http://llvm.org/viewvc/llvm-project?rev=302637&view=rev
Log:
[clang-tidy] Add new cert-dcl21-cpp check
This check flags postfix operator++/-- declarations,
where the return type is not a const object.
Differential Revision: https://reviews.llvm.org/D32743
Added:
clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.cpp
clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.h
clang-tools-extra/trunk/docs/clang-tidy/checks/cert-dcl21-cpp.rst
clang-tools-extra/trunk/test/clang-tidy/cert-dcl21-cpp.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
Modified: clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp?rev=302637&r1=302636&r2=302637&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp Wed May 10 06:16:55 2017
@@ -20,6 +20,7 @@
#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
#include "LimitedRandomnessCheck.h"
+#include "PostfixOperatorCheck.h"
#include "SetLongJmpCheck.h"
#include "StaticObjectExceptionCheck.h"
#include "StrToNumCheck.h"
@@ -35,6 +36,8 @@ public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
// C++ checkers
// DCL
+ CheckFactories.registerCheck<PostfixOperatorCheck>(
+ "cert-dcl21-cpp");
CheckFactories.registerCheck<VariadicFunctionDefCheck>("cert-dcl50-cpp");
CheckFactories.registerCheck<misc::NewDeleteOverloadsCheck>(
"cert-dcl54-cpp");
Modified: clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt?rev=302637&r1=302636&r2=302637&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/cert/CMakeLists.txt Wed May 10 06:16:55 2017
@@ -6,6 +6,7 @@ add_clang_library(clangTidyCERTModule
DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
+ PostfixOperatorCheck.cpp
SetLongJmpCheck.cpp
StaticObjectExceptionCheck.cpp
StrToNumCheck.cpp
Added: clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.cpp?rev=302637&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.cpp Wed May 10 06:16:55 2017
@@ -0,0 +1,88 @@
+//===--- PostfixOperatorCheck.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 "PostfixOperatorCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+void PostfixOperatorCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ Finder->addMatcher(functionDecl(anyOf(hasOverloadedOperatorName("++"),
+ hasOverloadedOperatorName("--")))
+ .bind("decl"),
+ this);
+}
+
+void PostfixOperatorCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("decl");
+
+ bool HasThis = false;
+ if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
+ HasThis = MethodDecl->isInstance();
+
+ // Check if the operator is a postfix one.
+ if (FuncDecl->getNumParams() != (HasThis ? 1 : 2))
+ return;
+
+ SourceRange ReturnRange = FuncDecl->getReturnTypeSourceRange();
+ SourceLocation Location = ReturnRange.getBegin();
+ if (!Location.isValid())
+ return;
+
+ QualType ReturnType = FuncDecl->getReturnType();
+
+ // Warn when the operators return a reference.
+ if (const auto *RefType = ReturnType->getAs<ReferenceType>()) {
+ auto Diag = diag(Location, "overloaded %0 returns a reference instead of a "
+ "constant object type")
+ << FuncDecl;
+
+ if (Location.isMacroID() || ReturnType->getAs<TypedefType>() ||
+ RefType->getPointeeTypeAsWritten()->getAs<TypedefType>())
+ return;
+
+ QualType ReplaceType =
+ ReturnType.getNonReferenceType().getLocalUnqualifiedType();
+ // The getReturnTypeSourceRange omits the qualifiers. We do not want to
+ // duplicate the const.
+ if (!ReturnType->getPointeeType().isConstQualified())
+ ReplaceType.addConst();
+
+ Diag << FixItHint::CreateReplacement(
+ ReturnRange,
+ ReplaceType.getAsString(Result.Context->getPrintingPolicy()) + " ");
+
+ return;
+ }
+
+ if (ReturnType.isConstQualified() || ReturnType->isBuiltinType() ||
+ ReturnType->isPointerType())
+ return;
+
+ auto Diag =
+ diag(Location, "overloaded %0 returns a non-constant object instead of a "
+ "constant object type")
+ << FuncDecl;
+
+ if (!Location.isMacroID() && !ReturnType->getAs<TypedefType>())
+ Diag << FixItHint::CreateInsertion(Location, "const ");
+}
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
Added: clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.h?rev=302637&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/cert/PostfixOperatorCheck.h Wed May 10 06:16:55 2017
@@ -0,0 +1,36 @@
+//===--- PostfixOperatorCheck.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_CERT_POSTFIX_OPERATOR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_POSTFIX_OPERATOR_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+/// Checks if the overloaded postfix ++ and -- operator return a constant
+/// object.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-postfix-operator.html
+class PostfixOperatorCheck : public ClangTidyCheck {
+public:
+ PostfixOperatorCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_POSTFIX_OPERATOR_H
Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=302637&r1=302636&r2=302637&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed May 10 06:16:55 2017
@@ -57,6 +57,11 @@ The improvements are...
Improvements to clang-tidy
--------------------------
+- New `cert-dcl21-cpp
+ <http://clang.llvm.org/extra/clang-tidy/checks/cert-dcl21-cpp.html>`_ check
+
+ Checks if the overloaded postfix ``operator++/--`` returns a constant object.
+
- New `cert-dcl58-cpp
<http://clang.llvm.org/extra/clang-tidy/checks/cert-dcl58-cpp.html>`_ check
Added: clang-tools-extra/trunk/docs/clang-tidy/checks/cert-dcl21-cpp.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/cert-dcl21-cpp.rst?rev=302637&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/cert-dcl21-cpp.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/cert-dcl21-cpp.rst Wed May 10 06:16:55 2017
@@ -0,0 +1,12 @@
+.. title:: clang-tidy - cert-dcl21-cpp
+
+cert-dcl21-cpp
+==============
+
+This check flags postfix ``operator++`` and ``operator--`` declarations
+if the return type is not a const object. This also warns if the return type
+is a reference type.
+
+This check corresponds to the CERT C++ Coding Standard recommendation
+`DCL21-CPP. Overloaded postfix increment and decrement operators should return a const object
+<https://www.securecoding.cert.org/confluence/display/cplusplus/DCL21-CPP.+Overloaded+postfix+increment+and+decrement+operators+should+return+a+const+object>`_.
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=302637&r1=302636&r2=302637&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed May 10 06:16:55 2017
@@ -6,6 +6,7 @@ Clang-Tidy Checks
.. toctree::
boost-use-to-string
cert-dcl03-c (redirects to misc-static-assert) <cert-dcl03-c>
+ cert-dcl21-cpp
cert-dcl50-cpp
cert-dcl54-cpp (redirects to misc-new-delete-overloads) <cert-dcl54-cpp>
cert-dcl58-cpp
Added: clang-tools-extra/trunk/test/clang-tidy/cert-dcl21-cpp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cert-dcl21-cpp.cpp?rev=302637&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cert-dcl21-cpp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cert-dcl21-cpp.cpp Wed May 10 06:16:55 2017
@@ -0,0 +1,134 @@
+// RUN: %check_clang_tidy %s cert-dcl21-cpp %t
+
+class A {};
+
+A operator++(A &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a non-constant object instead of a constant object type [cert-dcl21-cpp]
+// CHECK-FIXES: {{^}}const A operator++(A &, int);
+
+A operator--(A &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a no
+// CHECK-FIXES: {{^}}const A operator--(A &, int);
+
+class B {};
+
+B &operator++(B &);
+const B operator++(B &, int);
+
+B &operator--(B &);
+const B operator--(B &, int);
+
+
+class D {
+D &operator++();
+const D operator++(int);
+
+D &operator--();
+const D operator--(int);
+};
+
+class C {
+C operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a no
+// CHECK-FIXES: {{^}}const C operator++(int);
+
+C operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a no
+// CHECK-FIXES: {{^}}const C operator--(int);
+};
+
+class E {};
+
+E &operator++(E &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a reference instead of a constant object type [cert-dcl21-cpp]
+// CHECK-FIXES: {{^}}const E operator++(E &, int);
+
+E &operator--(E &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const E operator--(E &, int);
+
+class G {
+G &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const G operator++(int);
+
+G &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const G operator--(int);
+};
+
+class F {};
+
+const F &operator++(F &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const F operator++(F &, int);
+
+const F &operator--(F &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const F operator--(F &, int);
+
+class H {
+const H &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const H operator++(int);
+
+const H &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const H operator--(int);
+};
+
+
+#define FROM_MACRO P&
+class P {
+const FROM_MACRO operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const FROM_MACRO operator++(int);
+};
+
+
+template<typename T>
+class Q {
+const Q &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const Q<T> operator++(int);
+
+const Q &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const Q<T> operator--(int);
+};
+
+void foobar() {
+ Q<int> a;
+ Q<float> b;
+ (void)a;
+ (void)b;
+}
+
+struct S {};
+typedef S& SRef;
+
+SRef operator++(SRef, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}SRef operator++(SRef, int);
+
+struct T {
+ typedef T& TRef;
+
+ TRef operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}} TRef operator++(int);
+};
+
+struct U {
+ typedef const U& ConstURef;
+
+ ConstURef& operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}} ConstURef& operator++(int);
+};
+
+struct V {
+ V *operator++(int);
+ V *const operator--(int);
+};
+
More information about the cfe-commits
mailing list