Bug 36767 - [4.3/4.4 Regression] Segmentation fault with -fprofile-arcs -O2
Summary: [4.3/4.4 Regression] Segmentation fault with -fprofile-arcs -O2
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.1
: P1 normal
Target Milestone: 4.3.2
Assignee: Dodji Seketeli
URL:
Keywords: ice-on-valid-code
: 36768 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-07-09 07:31 UTC by Daniel Pinol
Modified: 2008-07-30 13:53 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.2.4
Known to fail: 4.3.1
Last reconfirmed: 2008-07-21 15:31:23


Attachments
fixes DECL_CONTEXT() of the temporary variables in the initialiser (1.17 KB, patch)
2008-07-25 00:03 UTC, Dodji Seketeli
Details | Diff
try scanning DECL_EXPR instead of VAR_DECLs directly. (1.25 KB, patch)
2008-07-28 07:19 UTC, Dodji Seketeli
Details | Diff
update vars more specifically, adding BIND_EXPR (1.31 KB, patch)
2008-07-28 10:52 UTC, Dodji Seketeli
Details | Diff
reworked patch (1.38 KB, patch)
2008-07-28 17:01 UTC, Dodji Seketeli
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Pinol 2008-07-09 07:31:21 UTC
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];
Comment 1 Richard Biener 2008-07-09 12:32:34 UTC
*** Bug 36768 has been marked as a duplicate of this bug. ***
Comment 2 Richard Biener 2008-07-09 12:53:06 UTC
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);
...
Comment 3 Jakub Jelinek 2008-07-15 15:09:21 UTC
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.
Comment 4 Dodji Seketeli 2008-07-21 15:31:22 UTC
Okay, I could reproduce this on gcc-4_3-branch. I will work on it, if nobody is working on it already.
Comment 5 Dodji Seketeli 2008-07-21 15:43:33 UTC
By the way, I cannot reproduce this on trunk, changeset 138026.
Comment 6 Dodji Seketeli 2008-07-22 18:25:11 UTC
@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.
Comment 7 Dodji Seketeli 2008-07-25 00:03:55 UTC
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.
Comment 8 Dodji Seketeli 2008-07-25 00:04:53 UTC
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.
Comment 9 Jason Merrill 2008-07-25 02:32:11 UTC
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.
Comment 10 Dodji Seketeli 2008-07-28 07:19:25 UTC
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 ?
Comment 11 Dodji Seketeli 2008-07-28 10:52:20 UTC
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.
Comment 12 Jakub Jelinek 2008-07-28 15:00:57 UTC
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.
Comment 13 Dodji Seketeli 2008-07-28 17:01:35 UTC
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.
Comment 14 Dodji Seketeli 2008-07-30 13:09:14 UTC
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

Comment 15 Dodji Seketeli 2008-07-30 13:19:56 UTC
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

Comment 16 Jakub Jelinek 2008-07-30 13:53:55 UTC
Fixed, thanks.