This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [FIXED] Generic lambda symbol table bug


On 07.08.2013 20:56, Adam Butcher wrote:
On 07.08.2013 16:59, Jason Merrill wrote:
On 08/07/2013 03:52 AM, Adam Butcher wrote:
But a cleaner way might be to extend the "processing
template declaration" state from lambda declarator all the way to the end of the lambda body. This would match with the scenario that occurs with a standard in-class member function template definition. To do that elegantly would
require a bit of refactoring of the lambda parser code.

It isn't already set through the whole lambda body?

No.  It is within cp_parser_lambda_declarator_opt.

That seems
necessary to support non-trivial lambda bodies; otherwise we won't be
able to handle dependence properly.

Agreed.  Okay, I will produce three patches:

  1) Refactor existing monomorphic implementation to give a cleaner
     parser separation of concerns; extract the fco creation and
     provide begin and end for the lambda function operator.

I did this---well not exactly as written---but I extended the template decl state through until the end of the lambda body. And it works with my dependence test. However, the previous version does too. The following program works fine (conv ops an all) with the refactored version and without it. I'm now questioning whether it is worth making any change in this area. What do you think? The test code is as follows and the resulting program correctly executes S::N::test() 4 times as expected -- were you thinking of some other dependence case?

  #include <iostream>

  struct S
  {
     struct N
     {
float test () { std::cout << "S::N::test() -> 7.f\n"; return 7.f; }
     };
  };

  int main()
  {
     auto f = [] <typename T> (T const& s) {
        typename T::N x;
        return x.test ();
     };
     auto g = [] (auto const& s) {
        typename std::decay<decltype (s)>::type::N x;
        return x.test ();
     };

     S i;

     f(i);
     g(i);

     float (*pfn) (S const&) = f;

     pfn(i);

     pfn = g;

     return pfn(i);
  }

Error messages are reasonable also. Omitting the necessary 'typename's gives:

   : need âtypenameâ before âT::Nâ because âTâ is a dependent scope
: need âtypenameâ before âtypename std::decay<decltype (s)>::type::Nâ because âtypename std::decay<decltype (s)>::typeâ is a dependent scope

Passing a local 'struct X {}' instead of 'S' gives:

: In instantiation of âauto main()::<lambda(const T&)> const [with T = main()::X]â:
  :24:9:   required from here
  :14:23: error: no type named âNâ in âstruct main()::Xâ
  ...

So all seems to be okay with both versions.  Any ideas why?

Cheers,
Adam


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]