https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70541
Maxim Ostapenko <m.ostapenko at samsung dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |m.ostapenko at samsung dot com --- Comment #1 from Maxim Ostapenko <m.ostapenko at samsung dot com> --- This bug also happens on current trunk. Consider slightly reduced testcase (just part of Christof's one): #include <stdlib.h> #include <stdio.h> struct Simple { int value; }; int f(struct Simple simple) { return simple.value; } int main() { int *pint = (int *) malloc(sizeof(int)); *pint = 24; free(pint); printf("%d\n", g(*pint)); return 0; } Corresponding gimple dump: main () { int D.3060; int D.3061; { struct Simple * psimple; psimple = malloc (4); psimple->value = 42; free (psimple); D.3060 = f (*psimple); <=========================== printf ("%d\n", D.3060); D.3061 = 0; return D.3061; } D.3061 = 0; return D.3061; } Here, GCC propagates *psimple directly to f() without creating temporary variable and ASan is unable to check it because it doesn't sanitize gimple calls arguments. I think the easiest way to fix this would be adding arguments checks in maybe_instrument_call, something like this: @@ -2060,7 +2067,20 @@ maybe_instrument_call (gimple_stmt_iterator *iter) return true; } - return false; + bool instrumented = false; + HOST_WIDE_INT args_num = gimple_call_num_args (stmt); + for (int i = 0; i < args_num; ++i) + { + if (is_arg_deref_p (TREE_CODE (gimple_call_arg (stmt, i)))) + { + instrument_derefs (iter, gimple_call_arg (stmt, i), + gimple_location (stmt), false); + instrumented = true; + } + } + if (instrumented) + gsi_next (iter); + return instrumented;