Следующий код С++ 11 является минимальным примером того, что, по моему мнению, вызывает ложный позитив в clang:
#include <iostream>
#include <list>
#include <memory>
class ElementType {};
int main(int argc, const char * argv[]) {
std::list<std::unique_ptr<ElementType>> theList(5);
theList.pop_front();
for (const auto &element: theList) { // (*)
std::cout << "This should be fine." << std::endl;
}
return 0;
}
В строке, помеченной звездочкой (*), анализатор clang утверждает, что
... filePath.../main.cpp: 21: 29: Использование памяти после ее освобождения (в пределах вызова "начать" )
Насколько я понимаю, этот код безвреден, но clang пропускает ту точку, в которой std::list<T>::pop_front()
не только вызывает деструктор своих элементов, но также перемещает местоположение std::list<T>::begin()
. Замена вызова на pop_front
на pop_back
приводит к тому, что предупреждение анализатора исчезает, и даже заменяя его на erase(theList.begin())
, оно выводится без предупреждения.
Я что-то упустил или действительно наткнулся на пропущенный случай в clang?
Для справки: Эти результаты исходят от XCode 5.1.1 (5B1008) в Mac OS X 10.9.2,
$ clang --version
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix