mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 12:39:19 +00:00
9a08a3fab9
Iterator modeling depends on container modeling, but not vice versa. This enables the possibility to arrange these two modeling checkers into separate layers. There are several advantages for doing this: the first one is that this way we can keep the respective modeling checkers moderately simple and small. Furthermore, this enables creation of checkers on container operations which only depend on the container modeling. Thus iterator modeling can be disabled together with the iterator checkers if they are not needed. Since many container operations also affect iterators, container modeling also uses the iterator library: it creates iterator positions upon calling the `begin()` or `end()` method of a containter (but propagation of the abstract position is left to the iterator modeling), shifts or invalidates iterators according to the rules upon calling a container modifier and rebinds the iterator to a new container upon `std::move()`. Iterator modeling propagates the abstract iterator position, handles the relations between iterator positions and models iterator operations such as increments and decrements. Differential Revision: https://reviews.llvm.org/D73547
59 lines
2.2 KiB
C++
59 lines
2.2 KiB
C++
// RUN: %clang_analyze_cc1 -std=c++11\
|
|
// RUN: -analyzer-checker=core,cplusplus\
|
|
// RUN: -analyzer-checker=debug.DebugIteratorModeling,debug.ExprInspection\
|
|
// RUN: -analyzer-config aggressive-binary-operation-simplification=true\
|
|
// RUN: -analyzer-config c++-container-inlining=false %s -verify
|
|
|
|
// RUN: %clang_analyze_cc1 -std=c++11\
|
|
// RUN: -analyzer-checker=core,cplusplus\
|
|
// RUN: -analyzer-checker=debug.DebugIteratorModeling,debug.ExprInspection\
|
|
// RUN: -analyzer-config aggressive-binary-operation-simplification=true\
|
|
// RUN: -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
|
|
|
|
#include "Inputs/system-header-simulator-cxx.h"
|
|
|
|
template <typename Container>
|
|
long clang_analyzer_container_begin(const Container&);
|
|
template <typename Container>
|
|
long clang_analyzer_container_end(const Container&);
|
|
template <typename Iterator>
|
|
long clang_analyzer_iterator_position(const Iterator&);
|
|
template <typename Iterator>
|
|
void* clang_analyzer_iterator_container(const Iterator&);
|
|
template <typename Iterator>
|
|
bool clang_analyzer_iterator_validity(const Iterator&);
|
|
void clang_analyzer_denote(long, const char*);
|
|
void clang_analyzer_express(long);
|
|
void clang_analyzer_dump(const void*);
|
|
void clang_analyzer_eval(bool);
|
|
|
|
void iterator_position(const std::vector<int> v0) {
|
|
auto b0 = v0.begin(), e0 = v0.end();
|
|
|
|
clang_analyzer_denote(clang_analyzer_container_begin(v0), "$b0");
|
|
clang_analyzer_denote(clang_analyzer_container_end(v0), "$e0");
|
|
|
|
clang_analyzer_express(clang_analyzer_iterator_position(b0)); // expected-warning{{$b0}}
|
|
clang_analyzer_express(clang_analyzer_iterator_position(e0)); // expected-warning{{$e0}}
|
|
|
|
++b0;
|
|
|
|
clang_analyzer_express(clang_analyzer_iterator_position(b0)); // expected-warning{{$b0 + 1}}
|
|
}
|
|
|
|
void iterator_container(const std::vector<int> v0) {
|
|
auto b0 = v0.begin();
|
|
|
|
clang_analyzer_dump(&v0); //expected-warning{{&v0}}
|
|
clang_analyzer_eval(clang_analyzer_iterator_container(b0) == &v0); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void iterator_validity(std::vector<int> v0) {
|
|
auto b0 = v0.begin();
|
|
clang_analyzer_eval(clang_analyzer_iterator_validity(b0)); //expected-warning{{TRUE}}
|
|
|
|
v0.clear();
|
|
|
|
clang_analyzer_eval(clang_analyzer_iterator_validity(b0)); //expected-warning{{FALSE}}
|
|
}
|