https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101688
Bug ID: 101688 Summary: g++.dg/warn/Wstringop-overflow-4.C fails on x86-32 with new jump threader Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: aldyh at gcc dot gnu.org CC: msebor at gcc dot gnu.org Target Milestone: --- Created attachment 51223 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51223&action=edit reduced testcase FAIL: g++.dg/warn/Wstringop-overflow-4.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/warn/Wstringop-overflow-4.C -std=gnu++17 (test for excess errors) FAIL: g++.dg/warn/Wstringop-overflow-4.C -std=gnu++2a (test for excess errors) FAIL: g++.dg/warn/Wstringop-overflow-4.C -std=gnu++98 (test for excess errors) Here are the new warnings: b.C:129:3: note: destination object of size [4, 6] allocated by ‘operator new []’ b.C:148:3: warning: ‘void* __builtin_memcpy(void*, const void*, unsigned int)’ writing 2 bytes into a region of size 0 [-Wstringop-overflow=] 148 | T (S (1), new int16_t[r_0_imax]); | ^ b.C:148:3: note: destination object of size 0 allocated by ‘operator new []’ b.C:149:3: warning: ‘void* __builtin_memcpy(void*, const void*, unsigned int)’ writing 3 bytes into a region of size 2 [-Wstringop-overflow=] 149 | T (S (2), new int16_t[r_0_imax + 1]); | ^ b.C:149:3: note: destination object of size 2 allocated by ‘operator new []’ What happens is that the new code is threading bb2 -> bb4 -> bb5, and is presumably confusing the -Wstringop-overflow pass. The transformation is correct as can be seen in the sequence below: <bb 2> : _34 ={v} signed_value_source; if (_34 < 0) goto <bb 4>; [50.00%] else goto <bb 3>; [50.00%] <bb 3> : <bb 4> : # iftmp.4_38 = PHI <0(2), _34(3)> r_0_imax.1_8 = (sizetype) iftmp.4_38; if (r_0_imax.1_8 <= 1073741822) goto <bb 5>; [INV] else goto <bb 6>; [INV] <bb 5> : iftmp.0_10 = r_0_imax.1_8 * 2; _12 = operator new [] (iftmp.0_10); __builtin_memcpy (_12, &MEM <const char[37]> [(void *)"0123456789abcdefghijklmnopqrstuvwxyz" + 35B], 2); sink (_12); _1 = iftmp.4_38 + 1; _17 = (sizetype) _1; if (_17 <= 1073741822) goto <bb 7>; [INV] else goto <bb 8>; [INV] The attached reduced testcase can be reproduced with: ./cc1plus a.ii -fdump-tree-all-details-graph -quiet -I/tmp -O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0 -m32 a.ii: In function ‘void test_strcpy_new_int16_t(size_t, const size_t*)’: a.ii:25:12: warning: ‘void* __builtin_memcpy(void*, const void*, unsigned int)’ writing 2 bytes into a region of size 0 [-Wstringop-overflow=] 25 | strcpy (d, s); | ~~~~~~~^~~~~~ a.ii:24:42: note: destination object of size 0 allocated by ‘operator new []’ 24 | char *d = (char*)new int16_t[r_0_imax]; //blah1 | ^ a.ii:32:12: warning: ‘void* __builtin_memcpy(void*, const void*, unsigned int)’ writing 3 bytes into a region of size 2 [-Wstringop-overflow=] 32 | strcpy (d, s); | ~~~~~~~^~~~~~ a.ii:31:46: note: destination object of size 2 allocated by ‘operator new []’ 31 | char *d = (char*)new int16_t[r_0_imax + 1]; //blah2 | ^