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(); } bool ento::shouldRegisterContainerModeling(const LangOptions &LO) { - return true; + return LO.CPlusPlus; } 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/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 +long clang_analyzer_container_end(const Container&); +template +long clang_analyzer_iterator_position(const Iterator&); + +void clang_analyzer_eval(bool); + + +template +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 &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)); + } +}