On Fri, Jan 27, 2017 at 7:45 AM, Nathan Sidwell <nat...@acm.org> wrote:
> Jason,
> I happened to be working on 67273, noticed a problem with my 77585 fix, and
> coincidentally 79253 got filed, which this also fixes.
>
> In 67253,  Wshadow checking was getting confused when determining the return
> type of an instantiated lambda.
>
> template <typename T> void Foo (T &&lambda) {
>   int ARG = 2;
>   lambda (1);
> }
>
> void Baz () {
>   Foo ([] (auto &&ARG) {});
> }
>
> maybe_instantiate_decl gets called when building the 'lambda (1)' call
> during the instantiation of Foo (to determine its return type).  It goes
> ahead and calls instantiate_decl.  instantiate_decl decides not to push to
> top level at:
>
>   fn_context = decl_function_context (d);
>   ...
>   if (!fn_context)
>     push_to_top_level ();
>   else
>     ...
>
> because 'decl_function_context' is true (it's 'Baz'), but the current
> function is 'Foo<closure_type>'.  We end up in store_parms thinking we're
> pushing a parm 'ARG' that shadows the local var 'ARG'.  That doesn't result
> in wrong code, but does give a spurious shadowing warning.
>
> Again, this is an artifact of generic lambdas being template members of
> function-scope classes.  Not a thing that exists elsewhere.
>
> Unfortunately, there is a case where we do want to stay at the current level
> -- when we're instantiating the lambda body during instantiation of the
> containing template function.  instantiate_decl must be told in which
> context it's being invoked.

Why can't it figure that out for itself?  We should be able to tell
whether its containing function is currently open.

Jason

Reply via email to