On Mon, 20 Feb 2023 at 10:26, Xi Ruoyao <xry111@xxxxxxxxxxx> wrote: > > On Sun, 2023-02-19 at 21:33 +0000, Jonny Grant wrote: > > > I noticed -Wanalyzer-null-dereference reports at build time a > > dereference. Also works if a function parameter. I wondered why > > std::string isn't detected by this static analyser option. > > Because the analyzer does not know the C++ standard disallows to use > NULL here. It just analyzes the code. The code in libstdc++ reads: > > basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) > : _M_dataplus(_M_local_data(), __a) > { > // NB: Not required, but considered best practice. > if (__s == 0) > std::__throw_logic_error(__N("basic_string: " > "construction from null is not valid")); > const _CharT* __end = __s + traits_type::length(__s); > _M_construct(__s, __end, forward_iterator_tag()); > } > > As you can see yourself, though the standard implies using NULL here is > a UB, libstdc++ does not really code a UB here. So the analyzer will > consider the code absolutely valid. Right, it's defined behaviour in libstdc++, as an extension. > > Note that throwing a C++ exception is not a programming error. It's > perfectly legal to catch the exception elsewhere. It's also perfectly > legal not to catch it and treat it as an abort() (calling abort is also > not a programming error). > > > > It's not pretty, but this wrapper catches NULL passed at compile time: > > > > std::string make_std_string(const char * const str) > > { > > // This line ensures: warning: dereference of NULL '0' [CWE-476] > > [-Wanalyzer-null-dereference] > > char b = *str; > > You are invoking an undefined behavior here if str is NULL, so it's > essentially same as using a nonnull attribute for make_std_string. And turned defined behaviour back into UB. The warning isn't reliable (only if the compiler can see the point is null, which isn't the case without optimization, or if the pointer comes from some non-inline function), the exception is. You're trading guaranteed exception for a not guaranteed warning and unbounded misoptimization due to undefined behaviour. Even if this was a robust solution, is it really a problem that needs to be solved?