llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.76k stars 10.96k forks source link

clangsa alpha.cplusplus.IteratorRange unsound on trivial example #61544

Open peckto opened 1 year ago

peckto commented 1 year ago

The alpha.cplusplus.IteratorRange checker is missing the following trivial example:

#include <vector>

int main() {
    std::vector<int> v;
    v.erase(v.begin(), v.begin() + 5);
    return 0;
}

v.begin() + 5 is clearly past-the-end iterator.

Whereas, in the following example the bug is reported:

#include <vector>

int main() {
    std::vector<int> v;
    for (auto &c : v) {
    }
    v.erase(v.begin(), v.begin() + 5);
    return 0;
}
$ clang++-16 --analyze -Xclang -analyzer-config -Xclang aggressive-binary-operation-simplification=true -Xanalyzer -analyzer-checker=alpha.cplusplus main.cpp
main.cpp:7:24: warning: Iterator incremented behind the past-the-end iterator [alpha.cplusplus.IteratorRange]
    v.erase(v.begin(), v.begin() + 5);
                       ^~~~~~~~~~~~~

(Same behavior when running via CodeChecker)

I have no clue why for loop is necessary to find the bug. Maybe it's too trivial and clangsa thinks, the variable is not used and cut by the optimizer? When executing, both example crash as expected with Segmentation fault.

Tested with clang-14 and clang-16:

Debian clang version 14.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Debian clang version 16.0.0 (++20230317013132+08d094a0e457-1~exp1~20230317133238.60)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-static-analyzer