Unverified Commit a6e7ba27 authored by Gennadiy Civil's avatar Gennadiy Civil Committed by GitHub
Browse files

Merge branch 'master' into josh/fix_scoped_class2

parents 21e51855 735bd75f
...@@ -59,6 +59,9 @@ ...@@ -59,6 +59,9 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing { namespace testing {
// Declares the flags. // Declares the flags.
...@@ -1179,4 +1182,6 @@ class StreamingListener : public EmptyTestEventListener { ...@@ -1179,4 +1182,6 @@ class StreamingListener : public EmptyTestEventListener {
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ #endif // GTEST_SRC_GTEST_INTERNAL_INL_H_
...@@ -294,6 +294,43 @@ void Mutex::AssertHeld() { ...@@ -294,6 +294,43 @@ void Mutex::AssertHeld() {
<< "The current thread is not holding the mutex @" << this; << "The current thread is not holding the mutex @" << this;
} }
namespace {
// Use the RAII idiom to flag mem allocs that are intentionally never
// deallocated. The motivation is to silence the false positive mem leaks
// that are reported by the debug version of MS's CRT which can only detect
// if an alloc is missing a matching deallocation.
// Example:
// MemoryIsNotDeallocated memory_is_not_deallocated;
// critical_section_ = new CRITICAL_SECTION;
//
class MemoryIsNotDeallocated
{
public:
MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
#ifdef _MSC_VER
old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
// doesn't report mem leak if there's no matching deallocation.
_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
#endif // _MSC_VER
}
~MemoryIsNotDeallocated() {
#ifdef _MSC_VER
// Restore the original _CRTDBG_ALLOC_MEM_DF flag
_CrtSetDbgFlag(old_crtdbg_flag_);
#endif // _MSC_VER
}
private:
int old_crtdbg_flag_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated);
};
} // namespace
// Initializes owner_thread_id_ and critical_section_ in static mutexes. // Initializes owner_thread_id_ and critical_section_ in static mutexes.
void Mutex::ThreadSafeLazyInit() { void Mutex::ThreadSafeLazyInit() {
// Dynamic mutexes are initialized in the constructor. // Dynamic mutexes are initialized in the constructor.
...@@ -304,7 +341,11 @@ void Mutex::ThreadSafeLazyInit() { ...@@ -304,7 +341,11 @@ void Mutex::ThreadSafeLazyInit() {
// If critical_section_init_phase_ was 0 before the exchange, we // If critical_section_init_phase_ was 0 before the exchange, we
// are the first to test it and need to perform the initialization. // are the first to test it and need to perform the initialization.
owner_thread_id_ = 0; owner_thread_id_ = 0;
critical_section_ = new CRITICAL_SECTION; {
// Use RAII to flag that following mem alloc is never deallocated.
MemoryIsNotDeallocated memory_is_not_deallocated;
critical_section_ = new CRITICAL_SECTION;
}
::InitializeCriticalSection(critical_section_); ::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal // Updates the critical_section_init_phase_ to 2 to signal
// initialization complete. // initialization complete.
...@@ -546,7 +587,8 @@ class ThreadLocalRegistryImpl { ...@@ -546,7 +587,8 @@ class ThreadLocalRegistryImpl {
// Returns map of thread local instances. // Returns map of thread local instances.
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
mutex_.AssertHeld(); mutex_.AssertHeld();
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; MemoryIsNotDeallocated memory_is_not_deallocated;
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
return map; return map;
} }
......
...@@ -138,6 +138,12 @@ ...@@ -138,6 +138,12 @@
# define vsnprintf _vsnprintf # define vsnprintf _vsnprintf
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#if GTEST_OS_MAC
#ifndef GTEST_OS_IOS
#include <crt_externs.h>
#endif
#endif
#if GTEST_HAS_ABSL #if GTEST_HAS_ABSL
#include "absl/debugging/failure_signal_handler.h" #include "absl/debugging/failure_signal_handler.h"
#include "absl/debugging/stacktrace.h" #include "absl/debugging/stacktrace.h"
...@@ -4692,7 +4698,7 @@ int UnitTest::Run() { ...@@ -4692,7 +4698,7 @@ int UnitTest::Run() {
// used for the duration of the program. // used for the duration of the program.
impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
#if GTEST_HAS_SEH #if GTEST_OS_WINDOWS
// Either the user wants Google Test to catch exceptions thrown by the // Either the user wants Google Test to catch exceptions thrown by the
// tests or this is executing in the context of death test child // tests or this is executing in the context of death test child
// process. In either case the user does not want to see pop-up dialogs // process. In either case the user does not want to see pop-up dialogs
...@@ -4729,7 +4735,7 @@ int UnitTest::Run() { ...@@ -4729,7 +4735,7 @@ int UnitTest::Run() {
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
# endif # endif
} }
#endif // GTEST_HAS_SEH #endif // GTEST_OS_WINDOWS
return internal::HandleExceptionsInMethodIfSupported( return internal::HandleExceptionsInMethodIfSupported(
impl(), impl(),
...@@ -5825,6 +5831,17 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { ...@@ -5825,6 +5831,17 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
// other parts of Google Test. // other parts of Google Test.
void ParseGoogleTestFlagsOnly(int* argc, char** argv) { void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
ParseGoogleTestFlagsOnlyImpl(argc, argv); ParseGoogleTestFlagsOnlyImpl(argc, argv);
// Fix the value of *_NSGetArgc() on macOS, but iff
// *_NSGetArgv() == argv
// Only applicable to char** version of argv
#if GTEST_OS_MAC
#ifndef GTEST_OS_IOS
if (*_NSGetArgv() == argv) {
*_NSGetArgc() = *argc;
}
#endif
#endif
} }
void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
ParseGoogleTestFlagsOnlyImpl(argc, argv); ParseGoogleTestFlagsOnlyImpl(argc, argv);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment