xazax.hun updated this revision to Diff 98097.
xazax.hun marked 3 inline comments as done.
xazax.hun added a comment.
- Fix alphabetical ordering of files in cmake.
- Let clang-format do its job.
https://reviews.llvm.org/D32743
Files:
clang-tidy/cert/CERTTidyModule.cpp
clang-tidy/cert/CMakeLists.txt
clang-tidy/cert/PostfixOperatorCheck.cpp
clang-tidy/cert/PostfixOperatorCheck.h
docs/ReleaseNotes.rst
docs/clang-tidy/checks/cert-dcl21-cpp.rst
docs/clang-tidy/checks/list.rst
test/clang-tidy/cert-dcl21-cpp.cpp
Index: test/clang-tidy/cert-dcl21-cpp.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/cert-dcl21-cpp.cpp
@@ -0,0 +1,78 @@
+// 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);
+};
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
.. 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
Index: docs/clang-tidy/checks/cert-dcl21-cpp.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/cert-dcl21-cpp.rst
@@ -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>`_.
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,11 @@
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
Index: clang-tidy/cert/PostfixOperatorCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/cert/PostfixOperatorCheck.h
@@ -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
Index: clang-tidy/cert/PostfixOperatorCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/cert/PostfixOperatorCheck.cpp
@@ -0,0 +1,77 @@
+//===--- 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() || Location.isMacroID())
+ return;
+
+ QualType ReturnType = FuncDecl->getReturnType();
+
+ // Warn when the operators return a reference.
+ if (ReturnType->isReferenceType()) {
+ auto Diag = diag(Location, "overloaded %0 returns a reference instead of a "
+ "constant object type")
+ << FuncDecl;
+
+ 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())
+ diag(Location, "overloaded %0 returns a non-constant object instead of a "
+ "constant object type")
+ << FuncDecl << FixItHint::CreateInsertion(Location, "const ");
+}
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/cert/CMakeLists.txt
===================================================================
--- clang-tidy/cert/CMakeLists.txt
+++ clang-tidy/cert/CMakeLists.txt
@@ -6,6 +6,7 @@
DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
+ PostfixOperatorCheck.cpp
SetLongJmpCheck.cpp
StaticObjectExceptionCheck.cpp
StrToNumCheck.cpp
Index: clang-tidy/cert/CERTTidyModule.cpp
===================================================================
--- clang-tidy/cert/CERTTidyModule.cpp
+++ clang-tidy/cert/CERTTidyModule.cpp
@@ -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 @@
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");
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits