baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, Szelethus.
baloghadamsoftware added a project: clang.
Herald added subscribers: martong, steakhal, Charusso, gamesh411, donat.nagy, 
mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun.

Iterator checkers (and planned container checkers) need the option 
`aggressive-binary-operation-simplification` to be enabled. Without this option 
they may cause assertions. To prevent such misuse, this patch adds a preventive 
check which issues a warning and denies the registartion of the checker if this 
option is disabled.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75171

Files:
  clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
  
clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp
  
clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp


Index: 
clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp
===================================================================
--- /dev/null
+++ 
clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: 
-analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection\
+// RUN: -analyzer-config c++-container-inlining=false %s 2>&1 | FileCheck %s
+
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: 
-analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection\
+// RUN: -analyzer-config c++-container-inlining=true -DINLINE=1 %s 2>&1 |\
+// RUN: FileCheck %s
+
+// CHECK: [ERROR] Checker alpha.cplusplus.ContainerModeling cannot be enabled 
without analyzer option aggressive-binary-operation-simplification.
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+template <typename Container>
+long clang_analyzer_container_end(const Container&);
+template <typename Iterator>
+long clang_analyzer_iterator_position(const Iterator&);
+
+void clang_analyzer_eval(bool);
+
+
+template <typename InputIterator, typename T>
+InputIterator nonStdFind(InputIterator first, InputIterator last,
+                         const T &val) {
+  for (auto i = first; i != last; ++i) {
+    if (*i == val) {
+      return i;
+    }
+  }
+  return last;
+}
+
+void non_std_find(std::vector<int> &V, int e) {
+  auto first = nonStdFind(V.begin(), V.end(), e);
+  clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                      clang_analyzer_iterator_position(first));
+  if (V.end() != first) {
+    clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                        clang_analyzer_iterator_position(first));
+  }
+}
Index: 
clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp
===================================================================
--- /dev/null
+++ 
clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: -analyzer-checker=core,cplusplus,alpha.cplusplus.ContainerModeling\
+// RUN: -analyzer-config c++-container-inlining=false %s 2>&1 | FileCheck %s
+
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: -analyzer-checker=core,cplusplus,alpha.cplusplus.ContainerModeling\
+// RUN: -analyzer-config c++-container-inlining=true -DINLINE=1 %s 2>&1 |\
+// RUN: FileCheck %s
+
+// CHECK: [ERROR] Checker alpha.cplusplus.ContainerModeling cannot be enabled 
without analyzer option aggressive-binary-operation-simplification.
Index: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
@@ -1031,10 +1031,23 @@
 
 } // namespace
 
+static bool checkAggressiveSimplificationEnabled(CheckerManager &mgr) {
+  if (!mgr.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) {
+    llvm::errs() << "[ERROR] Checker " << mgr.getCurrentCheckerName().getName()
+                 << " cannot be enabled without analyzer option aggressive-"
+                    "binary-operation-simplification.\n";
+    return false;
+  }
+  return true;
+}
+
 void ento::registerContainerModeling(CheckerManager &mgr) {
+  if (!checkAggressiveSimplificationEnabled(mgr))
+    return;
+
   mgr.registerChecker<ContainerModeling>();
 }
 
 bool ento::shouldRegisterContainerModeling(const LangOptions &LO) {
-  return true;
+  return LO.CPlusPlus;
 }


Index: clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection\
+// RUN: -analyzer-config c++-container-inlining=false %s 2>&1 | FileCheck %s
+
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection\
+// RUN: -analyzer-config c++-container-inlining=true -DINLINE=1 %s 2>&1 |\
+// RUN: FileCheck %s
+
+// CHECK: [ERROR] Checker alpha.cplusplus.ContainerModeling cannot be enabled without analyzer option aggressive-binary-operation-simplification.
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+template <typename Container>
+long clang_analyzer_container_end(const Container&);
+template <typename Iterator>
+long clang_analyzer_iterator_position(const Iterator&);
+
+void clang_analyzer_eval(bool);
+
+
+template <typename InputIterator, typename T>
+InputIterator nonStdFind(InputIterator first, InputIterator last,
+                         const T &val) {
+  for (auto i = first; i != last; ++i) {
+    if (*i == val) {
+      return i;
+    }
+  }
+  return last;
+}
+
+void non_std_find(std::vector<int> &V, int e) {
+  auto first = nonStdFind(V.begin(), V.end(), e);
+  clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                      clang_analyzer_iterator_position(first));
+  if (V.end() != first) {
+    clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                        clang_analyzer_iterator_position(first));
+  }
+}
Index: clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: -analyzer-checker=core,cplusplus,alpha.cplusplus.ContainerModeling\
+// RUN: -analyzer-config c++-container-inlining=false %s 2>&1 | FileCheck %s
+
+// RUN: %clang_analyze_cc1 -std=c++11\
+// RUN: -analyzer-checker=core,cplusplus,alpha.cplusplus.ContainerModeling\
+// RUN: -analyzer-config c++-container-inlining=true -DINLINE=1 %s 2>&1 |\
+// RUN: FileCheck %s
+
+// CHECK: [ERROR] Checker alpha.cplusplus.ContainerModeling cannot be enabled without analyzer option aggressive-binary-operation-simplification.
Index: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
@@ -1031,10 +1031,23 @@
 
 } // namespace
 
+static bool checkAggressiveSimplificationEnabled(CheckerManager &mgr) {
+  if (!mgr.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) {
+    llvm::errs() << "[ERROR] Checker " << mgr.getCurrentCheckerName().getName()
+                 << " cannot be enabled without analyzer option aggressive-"
+                    "binary-operation-simplification.\n";
+    return false;
+  }
+  return true;
+}
+
 void ento::registerContainerModeling(CheckerManager &mgr) {
+  if (!checkAggressiveSimplificationEnabled(mgr))
+    return;
+
   mgr.registerChecker<ContainerModeling>();
 }
 
 bool ento::shouldRegisterContainerModeling(const LangOptions &LO) {
-  return true;
+  return LO.CPlusPlus;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to