Hi, As mentioned in PR, the issue is that cddce1 marks the call to __builtin_strdup as necessary: marking necessary through .MEM_6 stmt p_7 = __builtin_strdup (&d); and since p_7 doesn't get added to worklist in propagate_necessity() because it's used only within free(), it's treated as "dead" and wrongly gets released. The patch fixes that by adding strdup/strndup in corresponding condition in eliminate_unnecessary_stmts(). Another issue, was that my previous patch failed to remove multiple calls to strdup: char *f(char **tt) { char *t = *tt; char *p; p = __builtin_strdup (t); p = __builtin_strdup (t); return p; } That's fixed in patch by adding strdup/strndup to another corresponding condition in propagate_necessity() so that only one instance of strdup would be kept. Bootstrapped+tested on x86_64-unknown-linux-gnu. Cross-testing on arm*-*-* and aarch64*-*-* in progress. OK to commit if testing passes ? Thanks Prathamesh