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: [PATCH 2/4] [lambda] Support implicit conversion of a stateless generic lambda to a function pointer.


Hi Jason,

On 03.08.2013 17:18, Jason Merrill wrote:
On 08/01/2013 08:25 AM, Adam Butcher wrote:
+    = DECL_TEMPLATE_INFO (callop)
+    && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop;

An expression broken across lines should be parenthesized.

And let's move the building of 'call' for the non-template case up to
be with the template case.

Done.

Otherwise, looks good!

Cheers. What should I do about the symtab nullptr issue? (http://gcc.gnu.org/ml/gcc-patches/2013-07/msg00043.html) Should I leave the workaround in my patch set as a standalone commit to be remedied later or should I try to squash it? Or is the hack appropriate for some reason?

It occurs when <iostream> is included (I'm assuming it will with other code too) when a generic lambda is defined (whether using 'auto' params or an explicit template param list). The following program is minimal and sufficient (with regard to the lambda expression) to cause it. I've deliberately used a capturing explicit lambda template below to remove the possibility that the conversion op or implicit template code has anything to do with it.

   #include <iostream>

   int main()
   {
     int i;
     [i] <typename T> (T) {};
   }

It does not matter whether the lambda is declared within a function or referenced by an initializer at namespace scope. The backtrace looks like this (when the nullptr checks are removed of course):

  0xaeea1f crash_signal
  	../../gcc/toplev.c:334
  0xcdff04 tree_check
  	../../gcc/tree.h:3899
  0xcdff04 decl_assembler_name_hash(tree_node const*)
  	../../gcc/tree.c:602
  0x8068cf insert_to_assembler_name_hash
	../../gcc/symtab.c:130
  0x806d91 symtab_initialize_asm_name_hash()
  	../../gcc/symtab.c:361
  0x806db8 symtab_node_for_asm(tree_node const*)
  	../../gcc/symtab.c:374
  0x810670 handle_alias_pairs
  	../../gcc/cgraphunit.c:1014
  0x81443c finalize_compilation_unit()
  	../../gcc/cgraphunit.c:2104
  0x62b7ce cp_write_global_declarations()
  	../../gcc/cp/decl2.c:4357

It occurs because at

  symtab.c:117   tree name = DECL_ASSEMBLER_NAME (node->symbol.decl);

'name' ends up being 0. GDB gives the following for debug_tree(node->symbol.decl) which may give you a clue:

 <function_decl 0x7ffff4f45900 operator()
    type <method_type 0x7ffff4f46a80
        type <template_type_parm 0x7ffff4f467e0 auto type_0 type_6 VOID
            align 8 symtab 0 alias set -1 canonical type 0x7ffff5c6c9d8
           index 0 level 2 orig_level 2
            chain <type_decl 0x7ffff4f3bc38 auto>>
        type_0 type_6 QI
        size <integer_cst 0x7ffff66fbf80 constant 8>
        unit size <integer_cst 0x7ffff66fbfa0 constant 1>
align 8 symtab 0 alias set -1 canonical type 0x7ffff4f46bd0 method basetype <record_type 0x7ffff4f465e8 __lambda0> arg-types <tree_list 0x7ffff4f42ed8 value <pointer_type 0x7ffff4f46b28> chain <tree_list 0x7ffff4f42e88 value <template_type_parm 0x7ffff4f46738 T> chain <tree_list 0x7ffff6707988 value <void_type 0x7ffff6716bd0 void>>>>> static external autoinline decl_3 decl_5 QI file bug.cpp line 6 col 22 align 16 context <record_type 0x7ffff4f465e8 __lambda0> initial <block 0x7ffff52ff9b0>
    arguments <parm_decl 0x7ffff4f44b00 __closure
type <pointer_type 0x7ffff4f46c78 type <record_type 0x7ffff4f469d8 __lambda0>
            readonly unsigned type_6 DI
            size <integer_cst 0x7ffff66fbdc0 constant 64>
            unit size <integer_cst 0x7ffff66fbde0 constant 8>
align 64 symtab 0 alias set -1 canonical type 0x7ffff4f46c78> readonly used unsigned DI file bug.cpp line 6 col 22 size <integer_cst 0x7ffff66fbdc0 64> unit size <integer_cst 0x7ffff66fbde0 8> align 64 context <function_decl 0x7ffff4f45900 operator()> arg-type <pointer_type 0x7ffff4f46c78> chain <parm_decl 0x7ffff4f44a80 D.29283 type <template_type_parm 0x7ffff4f46738 T>
            VOID file bug.cpp line 6 col 21
            align 8 context <function_decl 0x7ffff4f45900 operator()>
           >>
result <result_decl 0x7ffff52ed5a0 D.29288 type <template_type_parm 0x7ffff4f467e0 auto>
        ignored VOID file bug.cpp line 6 col 22
        align 8 context <function_decl 0x7ffff4f45900 operator()>>
    full-name "main()::<lambda(T)>"
    not-really-extern template-info 0x7ffff4f41c00
    struct-function 0x7ffff52cfbe0>

Do you know what could be causing this? Presumably something that's generated in the non-template lambda case needs to be removed in the template case (or something new added)? It is strange that it occurs only when <iostream> (or presumably some other headers) are included. With the two early outs for nullptrs in symtab.c the resulting programs behave as expected, I'm just not happy with that solution.

Cheers,
Adam


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