diff --git a/infer/tests/codetoanalyze/cpp/starvation/crossfile-1.cpp b/infer/tests/codetoanalyze/cpp/starvation/crossfile-1.cpp new file mode 100644 index 000000000..10ca63572 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/starvation/crossfile-1.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "crossfile-1.h" + +// a deadlock should be reported here +void CrossFileOne::lock_my_mutex_first_then_the_other() { + _mutex.lock(); + _other->just_lock_my_mutex(); + _mutex.unlock(); +} + +void CrossFileOne::just_lock_my_mutex() { + _mutex.lock(); + _mutex.unlock(); +} diff --git a/infer/tests/codetoanalyze/cpp/starvation/crossfile-1.h b/infer/tests/codetoanalyze/cpp/starvation/crossfile-1.h new file mode 100644 index 000000000..e1b6462c9 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/starvation/crossfile-1.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#ifndef CROSS_FILE_ONE +#define CROSS_FILE_ONE + +/* The goal of this test is to demonstrate that the per-file type +environments don't prevent the deadlock report here */ + +// unused include to distinguish the two per-file type environments +#include +#include + +class CrossFileOne; + +#include "crossfile-2.h" + +class CrossFileOne { + public: + CrossFileOne() {} + void lock_my_mutex_first_then_the_other(); + void just_lock_my_mutex(); + + private: + std::mutex _mutex; + CrossFileTwo* _other; +}; + +#endif diff --git a/infer/tests/codetoanalyze/cpp/starvation/crossfile-2.cpp b/infer/tests/codetoanalyze/cpp/starvation/crossfile-2.cpp new file mode 100644 index 000000000..c4ac8e7d0 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/starvation/crossfile-2.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "crossfile-2.h" + +// a deadlock should be reported here +void CrossFileTwo::lock_my_mutex_first_then_the_other() { + _mutex.lock(); + _other->just_lock_my_mutex(); + _mutex.unlock(); +} + +void CrossFileTwo::just_lock_my_mutex() { + _mutex.lock(); + _mutex.unlock(); +} diff --git a/infer/tests/codetoanalyze/cpp/starvation/crossfile-2.h b/infer/tests/codetoanalyze/cpp/starvation/crossfile-2.h new file mode 100644 index 000000000..d317bb708 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/starvation/crossfile-2.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* The goal of this test is to demonstrate that the per-file type +environments don't prevent the deadlock report here */ + +#ifndef CROSS_FILE_TWO +#define CROSS_FILE_TWO + +#include + +class CrossFileTwo; + +#include "crossfile-1.h" + +class CrossFileTwo { + public: + CrossFileTwo() {} + void lock_my_mutex_first_then_the_other(); + void just_lock_my_mutex(); + + private: + std::mutex _mutex; + CrossFileOne* _other; +}; + +#endif diff --git a/infer/tests/codetoanalyze/cpp/starvation/issues.exp b/infer/tests/codetoanalyze/cpp/starvation/issues.exp index bca150e38..ee15ad545 100644 --- a/infer/tests/codetoanalyze/cpp/starvation/issues.exp +++ b/infer/tests/codetoanalyze/cpp/starvation/issues.exp @@ -6,6 +6,8 @@ codetoanalyze/cpp/starvation/basics.cpp, basics::SelfDeadlock::interproc1_bad, 1 codetoanalyze/cpp/starvation/basics.cpp, basics::SelfDeadlock::thread_bad, 105, DEADLOCK, no_bucket, ERROR, [In method `basics::SelfDeadlock::thread_bad`, locks `this.mutex_` in `class basics::SelfDeadlock`, locks `this.mutex_` in `class basics::SelfDeadlock`] codetoanalyze/cpp/starvation/basics.cpp, basics::WithGuard::thread1_bad, 44, DEADLOCK, no_bucket, ERROR, [[Trace 1] `basics::WithGuard::thread1_bad`, locks `this.mutex_1` in `class basics::WithGuard`, locks `this.mutex_2` in `class basics::WithGuard`,[Trace 2] `basics::WithGuard::thread2_bad`, locks `this.mutex_2` in `class basics::WithGuard`, locks `this.mutex_1` in `class basics::WithGuard`] codetoanalyze/cpp/starvation/basics.cpp, basics::WithGuard::thread2_bad, 49, DEADLOCK, no_bucket, ERROR, [[Trace 1] `basics::WithGuard::thread2_bad`, locks `this.mutex_2` in `class basics::WithGuard`, locks `this.mutex_1` in `class basics::WithGuard`,[Trace 2] `basics::WithGuard::thread1_bad`, locks `this.mutex_1` in `class basics::WithGuard`, locks `this.mutex_2` in `class basics::WithGuard`] +codetoanalyze/cpp/starvation/crossfile-1.cpp, CrossFileOne::lock_my_mutex_first_then_the_other, 12, DEADLOCK, no_bucket, ERROR, [[Trace 1] `CrossFileOne::lock_my_mutex_first_then_the_other`, locks `this._mutex` in `class CrossFileOne`,Method call: `CrossFileTwo::just_lock_my_mutex`, locks `this._mutex` in `class CrossFileTwo`,[Trace 2] `CrossFileTwo::lock_my_mutex_first_then_the_other`, locks `this._mutex` in `class CrossFileTwo`,Method call: `CrossFileOne::just_lock_my_mutex`, locks `this._mutex` in `class CrossFileOne`] +codetoanalyze/cpp/starvation/crossfile-2.cpp, CrossFileTwo::lock_my_mutex_first_then_the_other, 12, DEADLOCK, no_bucket, ERROR, [[Trace 1] `CrossFileTwo::lock_my_mutex_first_then_the_other`, locks `this._mutex` in `class CrossFileTwo`,Method call: `CrossFileOne::just_lock_my_mutex`, locks `this._mutex` in `class CrossFileOne`,[Trace 2] `CrossFileOne::lock_my_mutex_first_then_the_other`, locks `this._mutex` in `class CrossFileOne`,Method call: `CrossFileTwo::just_lock_my_mutex`, locks `this._mutex` in `class CrossFileTwo`] codetoanalyze/cpp/starvation/skip.cpp, skipped::Skip::not_skipped_bad, 19, DEADLOCK, no_bucket, ERROR, [In method `skipped::Skip::not_skipped_bad`,Method call: `skipped::Skip::private_deadlock`, locks `this.mutex_` in `class skipped::Skip`, locks `this.mutex_` in `class skipped::Skip`] codetoanalyze/cpp/starvation/skip.cpp, skipped::SkipTemplate::not_skipped_bad, 44, DEADLOCK, no_bucket, ERROR, [In method `skipped::SkipTemplate::not_skipped_bad`,Method call: `skipped::SkipTemplate::private_deadlock`, locks `this.mutex_` in `class skipped::SkipTemplate`, locks `this.mutex_` in `class skipped::SkipTemplate`] codetoanalyze/cpp/starvation/skip.cpp, skipped::UseTemplate::foo, 53, DEADLOCK, no_bucket, ERROR, [In method `skipped::UseTemplate::foo`,Method call: `skipped::SkipTemplate::not_skipped_bad`,Method call: `skipped::SkipTemplate::private_deadlock`, locks `this.mutex_` in `class skipped::SkipTemplate`, locks `this.mutex_` in `class skipped::SkipTemplate`]