From 475b4f2d2ce12f6d2e42c42474296c62ee14af93 Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Tue, 9 Oct 2018 15:16:44 -0500 Subject: [PATCH] Tests: base/reference.cc - avoid "use after scope" gcc might be a bit forgiving with our use after scope here, unfortunately, clang isn't. Let's simply work around this issue by creating using a sentinel that simply resets the SmartPointer when going out of scope --- tests/base/reference.cc | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/tests/base/reference.cc b/tests/base/reference.cc index ccd664370b..a9f0d7951b 100644 --- a/tests/base/reference.cc +++ b/tests/base/reference.cc @@ -60,6 +60,29 @@ public: }; +// A sentinel that stores a reference to a SmartPointer and resets the +// Smartpointer in its destructor. + +template +class Sentinel +{ +public: + Sentinel(SmartPointer &smart_pointer) + : smart_pointer_(smart_pointer) + {} + + ~Sentinel() + { + // This assumes that the first object stored in SmartPointer is a raw + // pointer T* + *reinterpret_cast(&smart_pointer_) = nullptr; + } + +private: + SmartPointer &smart_pointer_; +}; + + int main() { @@ -94,9 +117,21 @@ main() // Now try if subscriptor works Test c("C"); r = &c; + + // We have to dance a happy little dance here: + // + // In our case the object D defined below will go out of scope before the + // smartpointer "Test R" does. Under normal circumstances this triggers + // an ExcNotUsed and aborts the program. BUT, this is a unit test and so, + // aborting on exception is disabled and we continue execution. + // Unfortunately, this triggers a "use after scope" memory access error + // when finally "Test R" goes out of scope and tries to unsubsribe from D + // that already got destructed. + // + // Work around this issue by creating a sentinel that gets destructed + // after D but before "Test R" that simply resets the SmartPointer. + Sentinel sentinel(r); + Test d("D"); r = &d; - // Destruction of "Test R" will cause a spurious ExcNotUsed here, - // since D was deleted first. This shows up in address sanitizers - // as stack-use-after-scope, but we can't do anything about it. } -- 2.39.5