zinovy.nis updated this revision to Diff 396869.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116478/new/

https://reviews.llvm.org/D116478

Files:
  clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
  clang-tools-extra/docs/clang-tidy/checks/bugprone-assert-side-effect.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone-assert-side-effect.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-assert-side-effect.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-assert-side-effect.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-assert-side-effect.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s bugprone-assert-side-effect %t -- -config="{CheckOptions: [{key: bugprone-assert-side-effect.CheckFunctionCalls, value: true}, {key: bugprone-assert-side-effect.AssertMacros, value: 'assert,assert2,my_assert,convoluted_assert,msvc_assert'}]}" -- -fexceptions
+// RUN: %check_clang_tidy %s bugprone-assert-side-effect %t -- -config="{CheckOptions: [{key: bugprone-assert-side-effect.CheckFunctionCalls, value: true}, {key: bugprone-assert-side-effect.AssertMacros, value: 'assert,assert2,my_assert,convoluted_assert,msvc_assert'}, {key: bugprone-assert-side-effect.FunctionExceptions, value: 'badButExceptedFunc'}]}" -- -fexceptions
 
 //===--- assert definition block ------------------------------------------===//
 int abort() { return 0; }
@@ -46,6 +46,7 @@
 class MyClass {
 public:
   bool badFunc(int a, int b) { return a * b > 0; }
+  bool badButExceptedFunc(int a, int b) { return a * b > 0; }
   bool goodFunc(int a, int b) const { return a * b > 0; }
 
   MyClass &operator=(const MyClass &rhs) { return *this; }
@@ -87,6 +88,7 @@
   MyClass mc;
   assert(mc.badFunc(0, 1));
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
+  assert(mc.badButExceptedFunc(0, 1));
   assert(mc.goodFunc(0, 1));
 
   MyClass mc2;
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-assert-side-effect.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/bugprone-assert-side-effect.rst
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-assert-side-effect.rst
@@ -21,3 +21,8 @@
    Whether to treat non-const member and non-member functions as they produce
    side effects. Disabled by default because it can increase the number of false
    positive warnings.
+
+.. option:: FunctionExceptions
+
+   A comma-separated list of the names of functions or methods to be
+   considered as not having side-effects.
Index: clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
+++ clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
@@ -10,6 +10,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_ASSERTSIDEEFFECTCHECK_H
 
 #include "../ClangTidyCheck.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include <string>
@@ -33,6 +34,7 @@
 ///     can increase the number of false positive warnings.
 class AssertSideEffectCheck : public ClangTidyCheck {
 public:
+  using FunctionExceptionType = llvm::SmallSet<StringRef, 3>;
   AssertSideEffectCheck(StringRef Name, ClangTidyContext *Context);
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
@@ -41,7 +43,9 @@
 private:
   const bool CheckFunctionCalls;
   const std::string RawAssertList;
+  const std::string RawFunctionExceptionsList;
   SmallVector<StringRef, 5> AssertMacros;
+  FunctionExceptionType FunctionExceptions;
 };
 
 } // namespace bugprone
Index: clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -25,7 +25,9 @@
 
 namespace {
 
-AST_MATCHER_P(Expr, hasSideEffect, bool, CheckFunctionCalls) {
+AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
+               AssertSideEffectCheck::FunctionExceptionType,
+               FunctionExceptions) {
   const Expr *E = &Node;
 
   if (const auto *Op = dyn_cast<UnaryOperator>(E)) {
@@ -55,7 +57,8 @@
     bool Result = CheckFunctionCalls;
     if (const auto *FuncDecl = CExpr->getDirectCallee()) {
       if (FuncDecl->getDeclName().isIdentifier() &&
-          FuncDecl->getName() == "__builtin_expect") // exceptions come here
+          FunctionExceptions.contains(
+              FuncDecl->getName())) // exceptions come here
         Result = false;
       else if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
         Result &= !MethodDecl->isConst();
@@ -72,20 +75,28 @@
                                              ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       CheckFunctionCalls(Options.get("CheckFunctionCalls", false)),
-      RawAssertList(Options.get("AssertMacros",
-                                "assert,NSAssert,NSCAssert")) {
+      RawAssertList(Options.get("AssertMacros", "assert,NSAssert,NSCAssert")),
+      RawFunctionExceptionsList("__builtin_expect," +
+                                Options.get("FunctionExceptions", "")) {
   StringRef(RawAssertList).split(AssertMacros, ",", -1, false);
+  SmallVector<StringRef> FunctionExceptionsVector;
+  StringRef(RawFunctionExceptionsList)
+      .split(FunctionExceptionsVector, ",", -1, false);
+  FunctionExceptions.insert(FunctionExceptionsVector.begin(),
+                            FunctionExceptionsVector.end());
 }
 
 // The options are explained in AssertSideEffectCheck.h.
 void AssertSideEffectCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "CheckFunctionCalls", CheckFunctionCalls);
   Options.store(Opts, "AssertMacros", RawAssertList);
+  Options.store(Opts, "FunctionExceptions", RawFunctionExceptionsList);
 }
 
 void AssertSideEffectCheck::registerMatchers(MatchFinder *Finder) {
   auto DescendantWithSideEffect =
-      traverse(TK_AsIs, hasDescendant(expr(hasSideEffect(CheckFunctionCalls))));
+      traverse(TK_AsIs, hasDescendant(expr(hasSideEffect(CheckFunctionCalls,
+                                                         FunctionExceptions))));
   auto ConditionWithSideEffect = hasCondition(DescendantWithSideEffect);
   Finder->addMatcher(
       stmt(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to