https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80944
--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #0)
> struct S { char *s; unsigned n; };
>
> void f (struct S *s)
> {
> __builtin_memset (s->s, 0, s->n);
> __builtin_free (s->s);
> __builtin_memset (s, 0, sizeof *s);
> __builtin_free (s);
> }
If you replace the first 2 lines of f with
char* t=s->s;
__builtin_memset (t, 0, s->n);
__builtin_free (t);
we optimize away both memset just fine. Consider:
struct S*s=malloc(sizeof(struct S));
s->s = s;
s->n = sizeof(char*);
f(s);
that is, the first memset may modify s->s, so it cannot be removed.