https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87363
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Status|UNCONFIRMED |NEW Last reconfirmed| |2018-09-19 CC| |msebor at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- The warning code tries to avoid duplicate warning by checking and setting TREE_NO_WARNING. But because it doesn't have access to the tree node representing the strlen(arg) call it uses TREE_NO_WARNING(arg). When the arg tree node changes for the same strlen(arg) call duplicate warnings aren't suppressed. Other than that, since When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values. the value of u.z is unspecified after the initialization of the union u in the test case. In strlen(u.z) the warning actually considers the value of u.x returned by string_constant(). This is because the function determines the initializer of an aggregate subobject by calling get_addr_base_and_unit_offset(), i.e., based on the subobject's offset. For the union in the test case, the offset of u.x is the same as u.z (there is no initializer for u.z and so the values of some of its bytes are unspecified). To avoid the warning, string_constant() could be enhanced to detect this case (i.e., referencing a union member) and give up. Or, we could consider the warning a useful reminder for people to avoid relying on unspecified behavior. Or we could add a different warning to help point out this sort of buggy code. To determine the number of non-nul bytes in aggregate object that includes multiple members, use memchr(&u, 0, sizeof u) instead of abusing strlen.