diff --git a/stl/inc/xiosbase b/stl/inc/xiosbase index e56578a265b..bf5bf3a072e 100644 --- a/stl/inc/xiosbase +++ b/stl/inc/xiosbase @@ -454,7 +454,7 @@ public: static void __CLRCALL_PURE_OR_CDECL _Addstd(ios_base*); // add standard stream - size_t _Stdstr; // if > 0 index of standard stream to suppress destruction + size_t _Stdstr{0}; // if > 0 index of standard stream to suppress destruction protected: __CLR_OR_THIS_CALL ios_base() {} @@ -547,9 +547,9 @@ private: fmtflags _Fmtfl; // format flags streamsize _Prec; // field precision streamsize _Wide; // field width - _Iosarray* _Arr; // pointer to first node of long/pointer array - _Fnarray* _Calls; // pointer to first node of call list - locale* _Ploc; // pointer to locale + _Iosarray* _Arr{nullptr}; // pointer to first node of long/pointer array + _Fnarray* _Calls{nullptr}; // pointer to first node of call list + locale* _Ploc{nullptr}; // pointer to locale __PURE_APPDOMAIN_GLOBAL static int _Index; __PURE_APPDOMAIN_GLOBAL static bool _Sync; diff --git a/stl/src/ios.cpp b/stl/src/ios.cpp index 8640a63169b..487ddadc21a 100644 --- a/stl/src/ios.cpp +++ b/stl/src/ios.cpp @@ -31,6 +31,7 @@ void __CLRCALL_PURE_OR_CDECL ios_base::_Ios_base_dtor(ios_base* _This) { // dest } _This->_Tidy(); + delete _This->_Ploc; } diff --git a/tests/std/test.lst b/tests/std/test.lst index adf5a624232..3648f6f7929 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -168,6 +168,7 @@ tests\GH_001017_discrete_distribution_out_of_range tests\GH_001059_hyperbolic_truncation tests\GH_001086_partial_sort_copy tests\GH_001103_countl_zero_correctness +tests\GH_001105_custom_streambuf_throws tests\GH_001123_random_cast_out_of_range tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function diff --git a/tests/std/tests/GH_001105_custom_streambuf_throws/env.lst b/tests/std/tests/GH_001105_custom_streambuf_throws/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_001105_custom_streambuf_throws/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_001105_custom_streambuf_throws/test.cpp b/tests/std/tests/GH_001105_custom_streambuf_throws/test.cpp new file mode 100644 index 00000000000..bb2a2df7c7d --- /dev/null +++ b/tests/std/tests/GH_001105_custom_streambuf_throws/test.cpp @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +struct bad_buf : std::streambuf { + bad_buf() { + throw std::runtime_error("throw in constructor!"); + } +}; + +struct custom_stream : std::istream { + custom_stream() : std::istream(new bad_buf{}) {} +}; + +int main() { + + { + // GH-1105 std::istream destructor should not crash if custom streambuf implementation throws. + try { + custom_stream f{}; + } catch (const std::runtime_error&) { + assert(true); + } + } + + return 0; +}