[committed] libstdc++: Replace operator>>(istream&, char*) [LWG 2499]

Jakub Jelinek jakub@redhat.com
Thu Aug 6 13:26:48 GMT 2020


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));
> 	  __in.width(0);
> 	  __in.setstate(ios_base::failbit);
> 	}
>       else
> 	{
> 	  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
/usr/include/bits/string_fortified.h.
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
+ abort.

	Jakub



More information about the Gcc-patches mailing list