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