Bug 2040927

Summary: 'stringop-overflow' diagnostic messaging occurring with valid code.
Product: Red Hat Developer Toolset Reporter: Brandon Clark <brclark>
Component: gccAssignee: Marek Polacek <mpolacek>
Status: CLOSED UPSTREAM QA Contact: Martin Cermak <mcermak>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: DTS 11.1 RHEL 7CC: alanm, amike, brclark, casantos, dmalcolm, jakub, jwright, mbliss, mcermak, mkielian, mkolbas, mnewsome, ohudlick, sipoyare
Target Milestone: alphaKeywords: Bugfix, Triaged
Target Release: 9.1   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: No Doc Update
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-04-12 16:00:06 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Test code file provide by customer facing issue. none

Description Brandon Clark 2022-01-14 22:12:48 UTC
Created attachment 1850855 [details]
Test code file provide by customer facing issue.

Description of problem:

Despite compiling valid code with a small-string-optimized class, diagnostic warnings are outputted for 'stringop-overflow' when using optimizations.

Version-Release number of selected component (if applicable):
devtoolset-11-gcc-11.2.1-1.2
devtoolset-11-gcc-c++-11.2.1-1.2

How reproducible:
Consistent when using optimizations.
Issue does not occur when no optimizations are used.

NOTE: Also tested on devtoolset-10-gcc 10.2.1. Only occurs when -O3 is used on that version.

Steps to Reproduce:
1. Compile code without optimization.
2. Observe non-issue behavior.
3. Compile with -O1
4. Observe Behavior
5. Compile with -O2
6. Observe Behavior (this time with additional diagnostic output).

Actual results:

'stringop-overflow' diagnostic error is observed.

Expected results:

Code compiles without warning.

Additional info:

A test code file has been attached for use in reproduction on your end.

Comment 1 Marek Polacek 2022-01-18 17:13:22 UTC
Reproduces with trunk too, so nothing to backport yet.  It's probably one of the bugs linked in here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=Wstringop-overflow

$ xg++ -c stringop-overflow-bug.cpp -Wall -O2
In member function ‘void String::append(const char*, const char*)’,
    inlined from ‘void String::append(const char*)’ at stringop-overflow-bug.cpp:54:15,
    inlined from ‘String& String::operator+=(const char*)’ at stringop-overflow-bug.cpp:82:15,
    inlined from ‘String operator+(String, const char*)’ at stringop-overflow-bug.cpp:86:15,
    inlined from ‘String foo(String)’ at stringop-overflow-bug.cpp:97:16:
stringop-overflow-bug.cpp:72:37: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   72 |         attr.data[attr.size + dist] = '\0';
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
stringop-overflow-bug.cpp: In function ‘String foo(String)’:
stringop-overflow-bug.cpp:16:14: note: at offset [49, 153] into destination object ‘String::Stack::data’ of size 23
   16 |         char data[23];
      |              ^~~~
In file included from /home/mpolacek/x/trunk/x86_64-pc-linux-gnu/libstdc++-v3/include/algorithm:60,
                 from stringop-overflow-bug.cpp:1:
In static member function ‘static _Tp* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = char; bool _IsMove = false]’,
    inlined from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = char*]’ at /home/mpolacek/x/trunk/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:495:30,
    inlined from ‘_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = char*]’ at /home/mpolacek/x/trunk/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:522:42,
    inlined from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = char*]’ at /home/mpolacek/x/trunk/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:529:31,
    inlined from ‘_OI std::copy(_II, _II, _OI) [with _II = const char*; _OI = char*]’ at /home/mpolacek/x/trunk/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:620:7,
    inlined from ‘void String::append(const char*, const char*)’ at stringop-overflow-bug.cpp:71:18,
    inlined from ‘void String::append(const char*)’ at stringop-overflow-bug.cpp:54:15,
    inlined from ‘String& String::operator+=(const char*)’ at stringop-overflow-bug.cpp:82:15,
    inlined from ‘String operator+(String, const char*)’ at stringop-overflow-bug.cpp:86:15,
    inlined from ‘String foo(String)’ at stringop-overflow-bug.cpp:97:16:
/home/mpolacek/x/trunk/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:431:30: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ forming offset [24, 48] is out of the bounds [0, 24] of object ‘s1’ with type ‘String’ [-Warray-bounds]
  431 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
stringop-overflow-bug.cpp: In function ‘String foo(String)’:
stringop-overflow-bug.cpp:95:8: note: ‘s1’ declared here
   95 | String foo(String s) {
      |        ^~~

Comment 2 Marek Polacek 2022-01-18 17:24:29 UTC
Started with r11-1183.

Comment 3 Marek Polacek 2022-01-18 18:03:56 UTC
And with -O3 the warning started with r273783.

Comment 4 Marek Polacek 2022-01-18 18:47:46 UTC
I think this is PR94335 which also started with r273783 as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335#c1 mentions.

Comment 5 Marek Polacek 2022-04-12 16:00:06 UTC
Unfortunately I don't expect this to be fixed anytime soon (and even if, the fix would probably not be backportable).  Deferring to upstream thus.