Hi Folks,
While working on flexible array members (FAM) and -fstrict-flex-arrays= flag, I realized that clang has a
(very) inconsistent behavior wrt. what is a flexible array member, depending on the context.
Currently, supported patterns are (for trailing arrays, obviously):
P1: type name[ ]; // C99 style, always legit
P2: type name[0]; //C89 style, GNU extension
P3: type name[1]; //C89 style, GNU extension
P4: type name[n]; // n> 1, supported for legacy compatibility, behavior varies depending on wether n is a literal, the result of a macro expansion or template parameter
The situation where being a flexible array member matters are:
S1: bound checking (under -Warray-bound)
S2: sanitizier checking (under -fsanitize=array-bounds)
S3: __builtin_object_size computation (to determine if the array type size is the real size)
But they handle very differently P4, basically depending on reported bug (let’s say it has grown organically).
Under -fstrict-flex-arrays=0, I think it’s safe to say that cases P1, P2 and P3
should be considered FAM in all situations. Considering P4 I’d like to make it
consistent by stating that if at least one of S1, S2, S3 consider it a FAM, all
of them should do so. Any other approach would be considered as a regression,
and clang users wouldn’t be happy with new warnings or new sanitizer failures
popping off for code that were considered legit before.
Doing so will probably miss a few warnings / sanitizer opportunity, but that
would only be for p4 & -fstrict-flex-arrays=0.
So, yeah, any thoughts?