https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Priority|P3 |P2
Status|UNCONFIRMED |NEW
Keywords|lto |
Last reconfirmed| |2018-06-21
CC| |msebor at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
Ever confirmed|0 |1
Summary|min(4, strlen(s)) optimized |[8/9 Regression] min(4,
|to strlen(s) with -flto |strlen(s)) optimized to
| |strlen(s) with -flto
Target Milestone|--- |8.2
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Vladimir Panteleev from comment #5)
> (In reply to Andrew Pinski from comment #2)
> > Note gcc thinks strlen(s) is less than or equal to 3 as s is really T.s
> > which is an array of 4 in size and there for the last element has to be a
> > null char.
>
> Hmm. Here is a simpler example which illustrates this:
>
> /////////////////// test.c ///////////////////
> #include <stdio.h>
> #include <string.h>
>
> struct S
> {
> int x[1];
> };
>
> union U
> {
> struct S arr[64];
> char s[256];
> };
>
> int main()
> {
> union U u;
> strcpy(u.s, "abcdefghijklmnopqrstuvwxyz");
> size_t len = strlen((char*)&u.arr[1].x);
> puts(len > 10 ? "YES" : "NO");
> return 0;
> }
> //////////////////////////////////////////////
>
> This prints "NO" with -O1 and above. clang always prints "YES".
>
> Are you sure this is an optimization the compiler is allowed to make,
> though? I would think that the explicit cast to char* removes all bets as to
> how long the string really is.
the explicit conversion to char * is unimportant (strlen formal argument
is of type const char * already). Indeed strlen may read any memory
and thus is not bound to type layout.
GCC optimizes this during CCP which nowadays uses get_range_strlen (),
IMHO indeed a questionable optimization we shouldn't perform. The
optimization happens because of
if (tree lhs = gimple_call_lhs (stmt))
if (TREE_CODE (lhs) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
set_range_info (lhs, VR_RANGE, minlen, maxlen);
and we compute maxlen to 3.
That function was designed for warnings we may not use it for optimization.