[committed] libstdc++: Replace operator>>(istream&, char*) [LWG 2499]
Thu Aug 6 14:01:14 GMT 2020
On 06/08/20 15:26 +0200, Jakub Jelinek via Libstdc++ wrote:
>On Thu, Aug 06, 2020 at 02:14:48PM +0100, Jonathan Wakely wrote:
>> template<typename _CharT, typename _Traits>
>> __attribute__((__nonnull__(2), __access__(__write_only__, 2)))
>> inline basic_istream<_CharT, _Traits>&
>> operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
>> size_t __n = __builtin_object_size(__s, 0);
>> if (__builtin_expect(__n < sizeof(_CharT), false))
>> // not even space for null terminator
>> __glibcxx_assert(__n >= sizeof(_CharT));
>> if (__n == (size_t)-1)
>> __n = __gnu_cxx::__numeric_traits<streamsize>::__max;
>> std::__istream_extract(__in, __s, __n / sizeof(_CharT));
>> return __in;
>> This will give a -Wstringop-overflow warning at -O0 and then overflow
>> the buffer, with undefined behaviour. And it will give no warning but
>> avoid the overflow when optimising. This isn't my preferred outcome,
>> I'd prefer to always get a warning, *and* be able to avoid the
>> overflow when optimising and the size is known.
>A way to get warning even at -O2 would be to call some external function
>in the if (__bos0 < sizeof(_CharT)) block, which wouldn't be optimized away
>and would have __attribute__((warning ("..."))) on it.
>See e.g. how glibc uses __warndecl e.g. in
>One can use alias attribute to have different warnings for the same external
>call (which could do e.g. what part of __glibcxx_assert does, call vprintf
Every time I've tried that I've found the requirement for an external
function to be frustrating. It means adding a new symbol to the
library, because it doesn't work for inline functions or function
templates, even with __attribute__((noinline)).
And we don't necessarily want it to abort, because that depends on a
macro defined by users, which isn't visible inside the library.
It shouldn't be this hard.
More information about the Libstdc++