https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77293
Bug ID: 77293 Summary: __builtin_object_size inconsistent for multidimensional arrays Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- While testing a patch for bug 71831 (as per https://gcc.gnu.org/ml/gcc-patches/2016-08/msg01363.html) I noticed some inconsistencies in how __builtin_object_size handles multidimensional arrays. The test case below shows that the built-in returns a different result depending on whether or not the offset in the expression is a constant. In particular, in type 1, when it is a constant the built-in evaluates to 1 while when it is not a constant it evaluates to 4 in this case. The manual suggests that 4 should be expected: "If the least significant bit is clear, objects are whole variables, if it is set, a closest surrounding subobject is considered the object a pointer points to." I don't need a fix for what I'm doing but it seems to me that the (type & 1) functionality has been a source of confusion (see also bug 44384) and would be best either deprecated or documented as less than fully reliable. (The documentation itself is ambiguous: what is "a closest surrounding subobject" of an element of a multidimensional array? Is it the higher-ranked subarray, the entire array object, or, when the array object is a member of a structure, is it the structure object? $ (set -x && cat xyz.c && for N in a 1; do /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -DN=$N -O2 xyz.c && ./a.out; done) + cat xyz.c static char x2x3[2][3]; #define strcpy(d, s) \ __builtin___strcpy_chk (d, s, __builtin_object_size (d, 1)) int main (void) { int a = 1; strcpy (&x2x3[0][1] + N, "abc"); } + for N in a 1 + /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -DN=a -O2 xyz.c + ./a.out + for N in a 1 + /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -DN=1 -O2 xyz.c xyz.c: In function ‘main’: xyz.c:4:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer __builtin___strcpy_chk (d, s, __builtin_object_size (d, 1)) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ xyz.c:10:3: note: in expansion of macro ‘strcpy’ strcpy (&x2x3[0][1] + N, "abc"); ^~~~~~ + ./a.out *** buffer overflow detected ***: ./a.out terminated ======= Backtrace: ========= /lib64/libc.so.6(+0x77d9e)[0x7f983241dd9e] /lib64/libc.so.6(__fortify_fail+0x37)[0x7f98324b7db7] ...