Message ID | cb1d2107-6bc0-6b39-a933-685f6580ac05@acm.org |
---|---|
State | New |
Headers | show |
Series | [PR,c++/86610] lambda captures in templates | expand |
On 1/16/19 4:48 PM, Nathan Sidwell wrote: > This PR reports a bug where we select a non-const operator function and > then apply it to a const object. That's happening because the > expression 'c[0]' is not dependent, so we figure end up resolving it. > But the lambda capture logic doesn't capture 'c' at that point and we > have a non-const qualified 'c'. At instantiation time we do the capture > and the by-value lambda results in const-qualified captures. > > Jason, the orginal test in process_outer_var_ref looked a little funky > -- why not just processing_template_decl? That would satisfy what the > comment says it checking. Anyway changing the test to check DECL's > type-dependency makes the right things happen, and a bootstrap passes. > Could you review please. Hmm, I don't remember exactly my rationale for deferring captures within a template, but if this doesn't obviously break anything it seems reasonable. Go ahead. Jason
On Wed, Jan 16, 2019 at 2:32 PM Jason Merrill <jason@redhat.com> wrote: > > On 1/16/19 4:48 PM, Nathan Sidwell wrote: > > This PR reports a bug where we select a non-const operator function and > > then apply it to a const object. That's happening because the > > expression 'c[0]' is not dependent, so we figure end up resolving it. > > But the lambda capture logic doesn't capture 'c' at that point and we > > have a non-const qualified 'c'. At instantiation time we do the capture > > and the by-value lambda results in const-qualified captures. > > > > Jason, the orginal test in process_outer_var_ref looked a little funky > > -- why not just processing_template_decl? That would satisfy what the > > comment says it checking. Anyway changing the test to check DECL's > > type-dependency makes the right things happen, and a bootstrap passes. > > Could you review please. > > Hmm, I don't remember exactly my rationale for deferring captures within > a template, but if this doesn't obviously break anything it seems > reasonable. Go ahead. > This caused: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88995 We are working on a smaller testcase.
2019-01-16 Nathan Sidwell <nathan@acm.org> PR c++/86610 * semantics.c (process_outer_var_ref): Only skip dependent types in templates. PR c++/86610 * g++.dg/cpp0x/pr86610.C: New. Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 267983) +++ cp/semantics.c (working copy) @@ -3438,10 +3438,9 @@ process_outer_var_ref (tree decl, tsubst } /* In a lambda within a template, wait until instantiation - time to implicitly capture. */ + time to implicitly capture a dependent type. */ if (context == containing_function - && DECL_TEMPLATE_INFO (containing_function) - && uses_template_parms (DECL_TI_ARGS (containing_function))) + && dependent_type_p (TREE_TYPE (decl))) return decl; if (lambda_expr && VAR_P (decl) Index: testsuite/g++.dg/cpp0x/pr86610.C =================================================================== --- testsuite/g++.dg/cpp0x/pr86610.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr86610.C (working copy) @@ -0,0 +1,31 @@ +// { dg-do run { target c++11 } } +// PR c++86610 lambda capture inside template + +struct C +{ + int operator[](int) + { return 1; } + + int operator[](int) const + { return 0; } // Want this one +}; + +int q() +{ + C c; + return [=] { return c[0]; }(); +} + +template <typename T> +int f() +{ + C c; + T d; + return [=] { return c[0]; }() + + [=] { return c[0] + d[0]; }(); +} + +int main() +{ + return q () + f<C>(); +}