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.