https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93332
Bug ID: 93332 Summary: target-dependent inaccurate range info for some expressions Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- This bug captures the problem behind the test failures reported in bug 92829. The test should produce the same warnings in all three compilations but the warnings depend on the different forms of the expressions that set the ranges of the integer variables in the test case, and also on the target. $ (set -x && cat t.C && for d in ALWAYS_WORKS ALWAYS_FAILS xxx; do /build/powerpc64le-linux/gcc-git-wt/gcc/xgcc -B /build/powerpc64le-linux/gcc-git-wt/gcc -D$d -O2 -S -Wall -ftrack-macro-expansion=0 t.C; done) + cat t.C typedef __SIZE_TYPE__ size_t; static size_t i; extern size_t vals[]; static inline size_t r (size_t x, size_t y) { size_t z = vals[i++]; return z < x || y < z ? x : z; } extern "C" char* strcpy (char*, const char*); void sink (void*); #define T(src, alloc) do { \ const char *s = src; \ char *d = (char*)alloc; \ strcpy (d, s); \ sink (d); \ } while (0) size_t r_1_2, r_2_3; void f (size_t vals[]) { #if ALWAYS_WORKS // Works on both powerpc64* and x86_64. int i = 0; size_t r_1_2 = (++i, vals[i] < 1 || 2 < vals[i] ? 1 : vals[i]); size_t r_2_3 = (++i, vals[i] < 2 || 3 < vals[i] ? 2 : vals[i]); #elif ALWAYS_FAILS // Second test fails on both powerpc64* and x86_64. if (r_1_2 < 1 || 2 < r_1_2) r_1_2 = 1; if (r_2_3 < 2 || 3 < r_2_3) r_2_3 = 2; #else // Second test fails only on powerpc64*. (void)&vals; size_t r_1_2 = r (1, 2); size_t r_2_3 = r (2, 3); #endif T ("1234", new short[r_1_2]); // { dg-warning "\\\[-Wstringop-overflow" } T ("12345678", new short[r_2_3]); // { dg-warning "\\\[-Wstringop-overflow" } } + for d in ALWAYS_WORKS ALWAYS_FAILS xxx + /build/powerpc64le-linux/gcc-git-wt/gcc/xgcc -B /build/powerpc64le-linux/gcc-git-wt/gcc -DALWAYS_WORKS -O2 -S -Wall -ftrack-macro-expansion=0 t.C t.C: In function 'void f(size_t*)': t.C:43:3: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' writing 5 bytes into a region of size between 2 and 4 [-Wstringop-overflow=] 43 | T ("1234", new short[r_1_2]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:43:3: note: at offset 0 to an object with size between 2 and 4 allocated by 'operator new []' here t.C:44:3: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' writing 9 bytes into a region of size between 4 and 6 [-Wstringop-overflow=] 44 | T ("12345678", new short[r_2_3]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:44:3: note: at offset 0 to an object with size between 4 and 6 allocated by 'operator new []' here + for d in ALWAYS_WORKS ALWAYS_FAILS xxx + /build/powerpc64le-linux/gcc-git-wt/gcc/xgcc -B /build/powerpc64le-linux/gcc-git-wt/gcc -DALWAYS_FAILS -O2 -S -Wall -ftrack-macro-expansion=0 t.C t.C: In function 'void f(size_t*)': t.C:43:3: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' forming offset 4 is out of the bounds [0, 4] [-Warray-bounds] 43 | T ("1234", new short[r_1_2]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ + for d in ALWAYS_WORKS ALWAYS_FAILS xxx + /build/powerpc64le-linux/gcc-git-wt/gcc/xgcc -B /build/powerpc64le-linux/gcc-git-wt/gcc -Dxxx -O2 -S -Wall -ftrack-macro-expansion=0 t.C t.C: In function 'void f(size_t*)': t.C:44:3: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' writing 9 bytes into a region of size between 4 and 6 [-Wstringop-overflow=] 44 | T ("12345678", new short[r_2_3]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:44:3: note: at offset 0 to an object with size between 4 and 6 allocated by 'operator new []' here The followings shows the output with a native x86_64-linux GCC. The output differs from the powerpc64le-linux cross in the third invocation. $ (set -x && for d in ALWAYS_WORKS ALWAYS_FAILS xxx; do /build/gcc-git-wt/gcc/xgcc -B /build/gcc-git-wt/gcc -D$d -O2 -S -Wall -ftrack-macro-expansion=0 t.C; done) + for d in ALWAYS_WORKS ALWAYS_FAILS xxx + /build/gcc-git-wt/gcc/xgcc -B /build/gcc-git-wt/gcc -DALWAYS_WORKS -O2 -S -Wall -ftrack-macro-expansion=0 t.C t.C: In function ‘void f(size_t*)’: t.C:43:3: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing 5 bytes into a region of size between 2 and 4 [-Wstringop-overflow=] 43 | T ("1234", new short[r_1_2]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:43:3: note: at offset 0 to an object with size between 2 and 4 allocated by ‘operator new []’ here t.C:44:3: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing 9 bytes into a region of size between 4 and 6 [-Wstringop-overflow=] 44 | T ("12345678", new short[r_2_3]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:44:3: note: at offset 0 to an object with size between 4 and 6 allocated by ‘operator new []’ here + for d in ALWAYS_WORKS ALWAYS_FAILS xxx + /build/gcc-git-wt/gcc/xgcc -B /build/gcc-git-wt/gcc -DALWAYS_FAILS -O2 -S -Wall -ftrack-macro-expansion=0 t.C t.C: In function ‘void f(size_t*)’: t.C:43:3: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ forming offset 4 is out of the bounds [0, 4] [-Warray-bounds] 43 | T ("1234", new short[r_1_2]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ + for d in ALWAYS_WORKS ALWAYS_FAILS xxx + /build/gcc-git-wt/gcc/xgcc -B /build/gcc-git-wt/gcc -Dxxx -O2 -S -Wall -ftrack-macro-expansion=0 t.C t.C: In function ‘void f(size_t*)’: t.C:43:3: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing 5 bytes into a region of size between 2 and 4 [-Wstringop-overflow=] 43 | T ("1234", new short[r_1_2]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:43:3: note: at offset 0 to an object with size between 2 and 4 allocated by ‘operator new []’ here t.C:44:3: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing 9 bytes into a region of size between 4 and 6 [-Wstringop-overflow=] 44 | T ("12345678", new short[r_2_3]); // { dg-warning "\\\[-Wstringop-overflow" } | ^ t.C:44:3: note: at offset 0 to an object with size between 4 and 6 allocated by ‘operator new []’ here