I am trying to get more useful warnings for array bounds. In particular I am interested in cases like this:
void foo(int (*a)[3], int n, int (*b)[n]) { (*a)[4] = 1; (*b)[n + 1] = 1; } That currently even the first assignment does not produce a warning is a bit disappointing. (clang does) There is also no warning in the following example when the array is the last element of a struct. struct h3 { int i; int j[3]; }; struct h3* h3 = malloc(sizeof(struct h) + 3 * sizeof(int)); h3->j[4] = 1; I guess this is to avoid warnings for the 'struct hack', but why is this not limited to arrays with size 0 (and maybe 1) and flexible array members? The relevant code is in the function check_array_ref in gcc/tree-vrp.c (see below). It seems that this code accidentally deactivates all warnings for arrays accessed through a pointer. Or is there a reason for returning when this is not a struct member? It also gives arrays which are the last member of a struct a free pass - even if they have a size greater than 1. Martin /* Accesses to trailing arrays via pointers may access storage beyond the types array bounds. */ base = get_base_address (ref); if (base && TREE_CODE (base) == MEM_REF) { tree cref, next = NULL_TREE; if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF) return; cref = TREE_OPERAND (ref, 0); if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE) for (next = DECL_CHAIN (TREE_OPERAND (cref, 1)); next && TREE_CODE (next) != FIELD_DECL; next = DECL_CHAIN (next)) ; /* If this is the last field in a struct type or a field in a union type do not warn. */ if (!next) return; }