On Tue, Nov 08, 2016 at 09:58:13AM +0100, Martin Liška wrote: > Problematic is lambda function (use-after-scope-ice-1.ii.004t.gimple): > C::AsyncCloseConnectionWithErrorMsg(const A&)::<lambda()> (const struct > __lambda0 * const __closure) > { > const struct A message [value-expr: __closure->__message]; > struct C * const this [value-expr: __closure->__this]; > > try > { > ASAN_MARK (2, &message, 4);
That shows that the ASAN_MARK adds the &message without going through gimplify_expr on it and therefore not handling the DECL_VALUE_EXPR in it, otherwise it would be _2 = &__closure->__message; ASAN_MARK (2, _2, 4); or something similar. That said, poisoning/unpoisoning the lambda captured vars inside of the lambda is of course wrong, 1) you really don't know where the members live, it could be on the stack, but could very well be on the heap or elsewhere, and while for stack and say longjmp we are prepared to unpoison it, for heap allocated vars you risk you keep the memory poisoned in corner cases and nothing will ever unpoison it; 2) the captured vars live longer than just in the lambda method, it is perhaps up to whatever function creates the lambda var to poison/unpoison it. > _1 = __closure->__this; > C::DispatchConnectionCloseEvent (_1, __closure->__message); > } > finally > { > ASAN_MARK (1, &message, 4); > } > } > > Where for quite obvious reasons variables 'message' can't be put as a stack > variable and ICE is triggered in: > /tmp/use-after-scope-ice-1.ii:31:23: internal compiler error: in > make_decl_rtl, at varasm.c:1311 > > My question is how to properly identify local variables defined in __closure > context? Is it somehow > related to DECL_HAS_VALUE_EXPR_P field set on a var? So yes, you should just ignore vars with DECL_HAS_VALUE_EXPR_P. That can mean lots of things (e.g. heavily used for OpenMP/OpenACC/Cilk+), but I can't think of a case which you would like to poison - if it is DECL_VALUE_EXPR to another var of part thereof, the other var should still be declared in its scope. Jakub