Jan Engelhardt via llvm-dev
2020-Jan-21 13:15 UTC
[llvm-dev] False positive #2, std::move warning on clang 9.0.1 --analyze
clang --analyze emits a warning about invoking functions on moved objects that should not be there. If you call subfld.reset() directly, the warning goes away. This suggests "reset" is hardcoded in the analyzer, and that it is only valid for the "first" nesting level. Having reset inside rezet and calling rezet, and the warning appears (as shown): » cat y.cpp #include <utility> template<typename T> struct object_ptr { // kind of like shared_ptr but (much)less for sake of testcase object_ptr() {} object_ptr(T *p) : m_ptr(p) {} object_ptr(object_ptr &&o) : m_ptr(o.m_ptr) { o.m_ptr = nullptr; } object_ptr &operator=(object_ptr &&o) { return *this; } ~object_ptr() { delete m_ptr; } T *operator->() const { return m_ptr; } void reset() { m_ptr = nullptr; } void rezet() { reset(); } T *m_ptr = nullptr; }; struct folder { void create_folder(folder **f); }; void func() { object_ptr<folder> fld{new folder}, subfld; fld = std::move(subfld); subfld.rezet(); } » clang++ --analyze /dev/shm/y.cpp -v clang version 9.0.1 Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/bin Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/10 Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/9 Found candidate GCC installation: /usr/lib64/gcc/x86_64-suse-linux/10 Found candidate GCC installation: /usr/lib64/gcc/x86_64-suse-linux/9 Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/10 Candidate multilib: .;@m64 Selected multilib: .;@m64 "/usr/bin/clang-9.0.1" -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name y.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -v -resource-dir /usr/lib64/clang/9.0.1 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/9.0.1/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /dev/shm -ferror-limit 19 -fmessage-length 0 -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -faddrsig -o y.plist -x c++ /dev/shm/y.cpp clang -cc1 version 9.0.1 based upon LLVM 9.0.1 default target x86_64-unknown-linux-gnu ignoring nonexistent directory "/include" #include "..." search starts here: #include <...> search starts here: /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10 /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/x86_64-suse-linux /usr/bin/../lib64/gcc/x86_64-suse-linux/10/../../../../include/c++/10/backward /usr/local/include /usr/lib64/clang/9.0.1/include /usr/include End of search list. y.cpp:22:2: warning: Method called on moved-from object 'subfld' subfld.rezet(); ^~~~~~~~~~~~~~ 1 warning generated.