https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108886
Bug ID: 108886 Summary: Add basic_string throw logic_error when assigned a nullptr Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: jg at jguk dot org Target Milestone: --- Checked this on godbolt trunk today. https://godbolt.org/z/6xxEc85c9 basic_string.h will throw a logic_error at runtime if a nullptr gets through to the basic_string() constructor. But assignment doesn't throw a logic_error, it gives SEGV. Could I suggest two improvements please: 1) Add throw logic_error to basic_string.h:815 if pointer is nullptr. _GLIBCXX20_CONSTEXPR basic_string& operator=(const _CharT* __s) { return this->assign(__s); } 2) Add throw logic_error to basic_string:1647 _GLIBCXX20_CONSTEXPR basic_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return _M_replace(size_type(0), this->size(), __s, traits_type::length(__s)); } This is what basic_string.h has for normal construction std::__throw_logic_error(__N("basic_string: " "construction from null is not valid")); The basic_string assignment = uses char_traits to check the length using __builtin_strlen and then SEGV. I believe it is the actual __builtin_strlen that does the nullptr dereference. GDB output Core was generated by `./str2'. Program terminated with signal SIGSEGV, Segmentation fault. #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142 142 ../sysdeps/x86_64/multiarch/strlen-sse2.S: No such file or directory. (gdb) bt #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142 #1 0x000055ca94a8327e in std::char_traits<char>::length (__s=0x0) at /usr/include/c++/12/bits/char_traits.h:395 #2 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__s=0x0, this=0x7fff26f1e370) at /usr/include/c++/12/bits/basic_string.h:1647 #3 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (__s=0x0, this=0x7fff26f1e370) at /usr/include/c++/12/bits/basic_string.h:815 #4 make_string (str=str@entry=0x0, out_string="") at str2.cpp:8 #5 0x000055ca94a832d9 in main () at str2.cpp:15 Therefore I propose 1) Add throw logic_error to basic_string.h:815 if pointer is nullptr. _GLIBCXX20_CONSTEXPR basic_string& operator=(const _CharT* __s) { return this->assign(__s); } 2) Add throw logic_error to basic_string:1647 _GLIBCXX20_CONSTEXPR basic_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return _M_replace(size_type(0), this->size(), __s, traits_type::length(__s)); } 3) I don't think char_traits allows exceptions, so I can't suggest a logic_error Is there anything else that could be added here? Maybe just a _GLIBCXX_DEBUG_PEDASSERT ? strlen() doesn't have a way to even set errno and return -1 This is what char_traits.h has /usr/include/c++/12/bits/char_traits.h:395:25: runtime error: null pointer passed as argument 1, which is declared to never be null AddressSanitizer:DEADLYSIGNAL /usr/include/c++/12/bits/char_traits.h static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { #if __cplusplus >= 201703L if (std::__is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::length(__s); #endif return __builtin_strlen(__s); } Example: #include <string> #include <cstdio> void make_string(const char * const str, std::string & out_string) { out_string = str; } int main() { const char * a = NULL; std::string str; make_string(a, str); printf("%s\n", str.c_str()); }