Hi, The code at the bottom compiled with this line gcc -fprofile-arcs -O2 -c kk.cpp causes this crash gcc: Internal error: Segmentation fault (program cc1plus) It occurs on both: * Suse 11.0 with gcc (SUSE Linux) 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (rpms: gcc43-4.3.1_20080507-6.1 and gcc-c++-4.3-39.1) * gcc 4.3.1 compiled with default options on Suse 10.2 best regards #include <vector> class PathElement { public: float a; ~PathElement() {} }; class PathPlanning { public: std::vector<PathElement> v; PathPlanning(); }; PathPlanning offset2[2];
*** Bug 36768 has been marked as a duplicate of this bug. ***
This one blows the stack recursing through #40147 0x000000000065fa9a in mangle_decl (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:2655 2655 tree id = get_identifier_nocopy (mangle_decl_string (decl)); (gdb) up #40148 0x0000000000d23724 in decl_assembler_name (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/tree.c:304 304 lang_hooks.set_decl_assembler_name (decl); (gdb) #40149 0x00000000006566c7 in write_unqualified_name (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:1104 1104 write_source_name (DECL_ASSEMBLER_NAME (decl)); (gdb) up #40150 0x000000000065471b in write_unscoped_name (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:884 884 write_unqualified_name (decl); (gdb) #40151 0x00000000006542d0 in write_name (decl=0x7f398018d0a0, ignore_local_scope=0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:818 818 write_unscoped_name (decl); (gdb) #40152 0x0000000000653b0c in write_encoding (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:738 738 write_name (decl, /*ignore_local_scope=*/0); (gdb) #40153 0x0000000000653329 in write_mangled_name (decl=0x7f398018d0a0, top_level=1 '\001') at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:708 708 write_encoding (decl); (gdb) #40154 0x000000000065f6a4 in mangle_decl_string (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:2631 2631 write_mangled_name (decl, true); (gdb) #40155 0x000000000065fa9a in mangle_decl (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/cp/mangle.c:2655 2655 tree id = get_identifier_nocopy (mangle_decl_string (decl)); (gdb) #40156 0x0000000000d23724 in decl_assembler_name (decl=0x7f398018d0a0) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/tree.c:304 304 lang_hooks.set_decl_assembler_name (decl); ...
Shorter testcase: // { dg-do compile } // { dg-options "-O2 -fprofile-arcs" } struct A { A (); ~A (); }; A a[2]; What seems to be going on is that: #0 create_temporary_var (type=0x7ffff3252780) at ../../gcc/cp/init.c:2613 #1 0x00000000005fd921 in get_temp_regvar (type=0x7ffff3252780, init=0x7ffff324d500) at ../../gcc/cp/init.c:2635 #2 0x00000000005fdfad in build_vec_init (base=0x7ffff324d500, maxindex=0x7ffff325c180, init=0x0, explicit_default_init_p=0 '\0', from_array=0, complain=tf_warning_or_error) at ../../gcc/cp/init.c:2759 #3 0x00000000005f71be in build_aggr_init (exp=0x7ffff3209e60, init=0x0, flags=0, complain=tf_warning_or_error) at ../../gcc/cp/init.c:1279 #4 0x000000000044b5de in build_aggr_init_full_exprs (decl=0x7ffff3209e60, init=0x0, flags=0) at ../../gcc/cp/decl.c:4978 #5 0x000000000044c648 in check_initializer (decl=0x7ffff3209e60, init=0x0, flags=0, cleanup=0x7fffffffde00) at ../../gcc/cp/decl.c:5104 #6 0x000000000044fc53 in cp_finish_decl (decl=0x7ffff3209e60, init=0x0, init_const_expr_p=0 '\0', asmspec_tree=0x0, flags=0) at ../../gcc/cp/decl.c:5579 creates a VAR_DECL while current_function_decl == NULL. Later on one_static_initialization_or_destruction puts all its uses (and DECL_EXPR for it) into the artificial __static_initialization_or_destruction, but from what I can see nothing actually fixes up DECL_CONTEXT of the variable to the function it has been put into. If I manually set DECL_CONTEXT of these variables in one_static_initialization_or_destruction, it compiles just fine. If not and the vars make it through to the expander, they have DECL_NAME () == NULL and that leads to infinite recursion during mangling. I wonder where is the best place to fix the contexts up though. Either one_static_initialization_or_destruction could walk_tree init, look for DECL_EXPRs with artificial VAR_DECLs with NULL DECL_CONTEXT, or say cp-gimplify.c could do that.
Okay, I could reproduce this on gcc-4_3-branch. I will work on it, if nobody is working on it already.
By the way, I cannot reproduce this on trunk, changeset 138026.
@jakub: I confirm that doing: if (!DECL_CONTEXT (decl)) { DECL_CONTEXT (decl) = current_function_decl; } at the beginning of one_static_initialization_or_destruction() allows the compilation to not crash. At that point, the name of current_function_decl is effectively "__static_initialization_and_destruction_0". I am not sure if setting DECL_CONTEXT (decl) is safe to do, because the DECL_CONTEXT (decl) being NULL means the variable happened in the global namespace. Doing DECL_CONTEXT (decl) = current_function_decl makes us loose that information. On the other hand, one_static_initialization_or_destruction() is called at the end of the parsing+semantic analysis phase, so loosing that information might not be harmful (I am not sure). In which case, this candidate fix might be enough.
Created attachment 15957 [details] fixes DECL_CONTEXT() of the temporary variables in the initialiser So this patch seems to make the crash go away for me. I still need to add add some asserts in the mangler to prevent it from recursing ad infinitum when a VAR_DECL has a NULL name.
By the way, I can reproduce the problem on trunk. I think I was lacking sleep when I first said I could not reproduce it on trunk. Sorry.
I accidentally checked in the demangler patch with my defaulted/deleted functions work today, so you don't need to worry about that. :) As for the patch itself, does it work to scan for DECL_EXPRs instead of the decls themselves? I'm a bit concerned about the current patch touching decls that it shouldn't.
Created attachment 15968 [details] try scanning DECL_EXPR instead of VAR_DECLs directly. @Jason: I have tried scanning DECL_EXPR and setting only VAR_DECL that are children of DECL_EXPR. It does not work. This patch is what I have done. Maybe I have done something bad ? My understanding is that by walking DECL_EXPRs and getting their associated VAR_DECL (using DECL_EXPR_DECL), all VAR_DECLs should be touched because every single variable must be declared at least once. So, are there cases where a VAR_DECL has never had a parent DECL_EXPR ?
Created attachment 15969 [details] update vars more specifically, adding BIND_EXPR After talking with Jakub, it appeared that I was forgetting to update VAR_DECLS that were attached to a BIND_EXPR. Walking those VAR_DECLS appears to fix the problem. Regtesting now. Will update the patch with a proper testcase when regtesting passes. Please feel free to comment in the meantime.
There are unneeded {} pairs, when there is just one statement in for/if, you should just write if (something) DECL_CONTEXT (x) = current_function_decl; and similar for for (.....) if (something) DECL_CONTEXT (var) = current_function_decl. Also, I think it is unnecessary to pass current_function_decl as data to the callback, current_function_decl is accessible in the callback too.
Created attachment 15972 [details] reworked patch Reworked patch to walk BIND_EXPR_VARs only. I think there is no need to walk VAR_DECLs via DECL_EXPR() if we walk BIND_EXPR_VARs. The patch seems to work, regtested on trunk, x86_64. @jakub: thanks for your comments. I did fix the patch accordingly.
Subject: Bug 36767 Author: dodji Date: Wed Jul 30 13:07:50 2008 New Revision: 138308 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=138308 Log: 2008-07-30 Dodji Seketeli <dseketel@redhat.com> PR c++/36767 * decl2.c (fix_temporary_vars_context_r): New function. (one_static_initialization_or_destruction): Make sure temporary variables part of the initialiser have their DECL_CONTEXT() properly set. Added: trunk/gcc/testsuite/g++.dg/parse/crash42.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/decl2.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 36767 Author: dodji Date: Wed Jul 30 13:18:31 2008 New Revision: 138309 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=138309 Log: 2008-07-30 Dodji Seketeli <dseketel@redhat.com> PR c++/36767 * decl2.c (fix_temporary_vars_context_r): New function. (one_static_initialization_or_destruction): Make sure temporary variables part of the initialiser have their DECL_CONTEXT() properly set. Added: branches/gcc-4_3-branch/gcc/testsuite/g++.dg/parse/crash41.C Modified: branches/gcc-4_3-branch/gcc/cp/ChangeLog branches/gcc-4_3-branch/gcc/cp/decl2.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
Fixed, thanks.