diff --git a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index da3ce01d032be8..a38298a7abedc8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -104,7 +104,7 @@ class MoveChecker "basic_ios", "future", "optional", - "packaged_task" + "packaged_task", "promise", "shared_future", "shared_lock", diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index 9010ce2bb9b6c0..a0759479bfebf8 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -1133,4 +1133,9 @@ class default_searcher { operator()( ForwardIt2 first, ForwardIt2 last ) const; }; -} +template class packaged_task; +template class packaged_task { + // TODO: Add some actual implementation. +}; + +} // namespace std diff --git a/clang/test/Analysis/use-after-move.cpp b/clang/test/Analysis/use-after-move.cpp index d7b6c74fabd6c1..d1278cad4c4f25 100644 --- a/clang/test/Analysis/use-after-move.cpp +++ b/clang/test/Analysis/use-after-move.cpp @@ -974,3 +974,19 @@ void getAfterMove(std::unique_ptr P) { // TODO: Warn on a null dereference here. a->foo(); } + +struct OtherMoveSafeClasses { + std::packaged_task Task; + + void test() { + // Test the suppression caused by use-after-move semantics of + // std::package_task being different from other standard classes. + // Only warn in aggressive mode. Don't say that the object + // is left in unspecified state after move. + std::packaged_task Task2 = std::move(Task); + // aggressive-note@-1 {{Object 'Task' is moved}} + std::packaged_task Task3 = std::move(Task); + // aggressive-warning@-1{{Moved-from object 'Task' is moved}} + // aggressive-note@-2 {{Moved-from object 'Task' is moved}} + } +};