Bug 79755 - [11/12/13/14 Regression] ICE: segfault in cgraph_node::get, at cgraph.h:1261
Summary: [11/12/13/14 Regression] ICE: segfault in cgraph_node::get, at cgraph.h:1261
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0.1
: P4 normal
Target Milestone: 11.5
Assignee: Not yet assigned to anyone
URL:
Keywords: error-recovery, ice-checking, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2017-02-28 17:18 UTC by Gerhard Steinmetz
Modified: 2023-07-07 10:32 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-12-12 00:00:00


Attachments
Patch for this bug (454 bytes, application/mbox)
2020-03-18 00:16 UTC, Nicholas Krause
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Gerhard Steinmetz 2017-02-28 17:18:01 UTC
Affects versions down to 4.9 (configured with --enable-checking=yes) :


$ cat z1.c
void foo () {}
#pragma weak foo = _foo
int _foo = 0;


$ gcc-7-20170226 -c z1.c
z1.c:1:6: error: 'foo' defined both normally and as 'alias' attribute
 void foo () {}
      ^~~
z1.c:1:6: error: 'foo' alias in between function and variable is not supported
z1.c:3:5: warning: '_foo' aliased declaration
 int _foo = 0;
     ^~~~
z1.c:1:6: internal compiler error: Segmentation fault
 void foo () {}
      ^~~
0xbf9f9f crash_signal
        ../../gcc/toplev.c:337
0x7f25e2 cgraph_node::get(tree_node const*)
        ../../gcc/cgraph.h:1261
0x7f25e2 cgraph_node::analyze()
        ../../gcc/cgraphunit.c:630
0x7f5d93 analyze_functions
        ../../gcc/cgraphunit.c:1118
0x7f68da symbol_table::finalize_compilation_unit()
        ../../gcc/cgraphunit.c:2599
Comment 1 Marek Polacek 2017-02-28 17:26:02 UTC
Started with r199577.
Comment 2 Marek Polacek 2017-02-28 17:28:24 UTC
Forgot to set Target Milestone.
Comment 3 Jakub Jelinek 2018-10-26 10:19:50 UTC
GCC 6 branch is being closed
Comment 4 Richard Biener 2019-11-14 07:55:18 UTC
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
Comment 5 Jakub Jelinek 2020-03-04 09:49:27 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 6 Nicholas Krause 2020-03-05 19:12:14 UTC
Does not happen on gcc 9.2. Does the gcc 8.5 branch have these functions, 	 cgraph_function_or_thunk_node or varpool_variable_node as those were removed on trunk and I'm suspecting that's were the problem is.
Comment 7 Jakub Jelinek 2020-03-05 19:43:39 UTC
This does happen even with 9.2 and current trunk, you just need to read the first line in #c0.
Comment 8 Nicholas Krause 2020-03-05 19:56:56 UTC
(In reply to Jakub Jelinek from comment #7)
> This does happen even with 9.2 and current trunk, you just need to read the
> first line in #c0.

While I ran it as on a Ubuntu 9.2 Toolchain configured as:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.2.1-9ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-gcc -c test.c-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2) 

like this:
gcc -c test.c

and this is my source code:
void foo () {}
  2 #pragma weak foo = _foo
  3 int _foo = 0;

and I get this:
test.c:1:6: error: ‘foo’ defined both normally and as ‘alias’ attribute
    1 | void foo () {}
      |      ^~~
test.c:1:6: error: ‘foo’ alias between function and variable is not supported
test.c:3:5: note: aliased declaration here
    3 | int _foo = 0;
      |     ^~~~
test.c:1: confused by earlier errors, bailing out

So no it does not appear to segfault on 9.2 not sure about trunk.
Comment 9 Nicholas Krause 2020-03-05 19:58:45 UTC
Sorry source code is:
void foo () {}
#pragma weak foo = _foo
int _foo = 0;

Copy and Pasted line numbers by mistake.
Comment 10 Jakub Jelinek 2020-03-05 19:59:07 UTC
--enable-checking=release (the default on release branches) is not --enable-checking=yes (which is needed to reproduce this checking error-recovery failure).
Comment 11 Andrew Pinski 2020-03-05 20:01:18 UTC
(In reply to Nicholas Krause from comment #8)
> test.c:1: confused by earlier errors, bailing out
> 
> So no it does not appear to segfault on 9.2 not sure about trunk.

YES it does.  Just GCC is being smart here when configured with --enable-checking=release (the default for releases) and just prints out "confused by earlier errors, bailing out" for all ICEs after an error has happened.
This is why Jakub's comment #7:
"This does happen even with 9.2 and current trunk, you just need to read the first line in #c0."
The first line in #c0 was:
Affects versions down to 4.9 (configured with --enable-checking=yes)

Which means you need --enable-checking=yes (and not --enable-checking=release) to get the full ICE happening.
Comment 12 Nicholas Krause 2020-03-05 20:32:57 UTC
Sorry about not reading the comment carefully.

I'm not if this helps but after looking at the change to this file:
https://gcc.gnu.org/viewcvs/gcc/trunk/gcc/cgraph.c?r1=199577&r2=199576&pathrev=199577

n = cgraph_create_function_alias (alias, decl);

was never changed for creating with the new function arguments as found here:
struct cgraph_node *
cgraph_create_function_alias (tree alias, tree target)

and therefore it should be:

n = cgraph_create_function_alias (alias, target);

and not decl.
Comment 13 Nicholas Krause 2020-03-05 21:30:38 UTC
Please forget the previous comment in verify_edge_corresponds_to_fndecl we need to switch it to this:
if (e->callee->former_clone_of != node->symbol.decl
&& (!n->symbol.cpp_implicit_alias	 
|| e->callee->former_clone_of != alias_node->symbol.alias_target ))

from the current:
 if (e->callee->former_clone_of != node->symbol.decl

as those other cases are missing in the patch posted after looking at it.
Comment 14 Nicholas Krause 2020-03-18 00:16:46 UTC
Created attachment 48052 [details]
Patch for this bug
Comment 15 Nicholas Krause 2020-03-18 00:17:38 UTC
(In reply to Nicholas Krause from comment #14)
> Created attachment 48052 [details]
> Patch for this bug

After tracking this down to the new function that replaced verify_edge_corresponds_to_fndecl, cgraph_edge::verify_corresponds_to_fndecl
which is basically the same we run into this:
if (callee->former_clone_of != node->decl
      && (node != callee->ultimate_alias_target ())
      && !clone_of_p (node, callee))


 Basically it appears to be checking we are a former cgraph clone at the same time as being a current clone or the same node with clone_of_p on the callee cgraph node. I'm attaching a test patch for this. Gerhard does this fix the issue?
Comment 16 Marek Polacek 2020-03-18 00:26:34 UTC
That patch will generate a -Wparentheses warning, and more importantly, doesn't fix the ICE, which you could have tried by yourself.
Comment 17 Nicholas Krause 2020-03-18 03:38:36 UTC
Sorry about that. I've managed to track it down to a problem with a alias issue 
And from reading the code in the original cvs commit. I'm not able to read it currently but the original function mentioned seems to now be cgraph_edge::verify_corresponds_to_fndecl. I've tried to access the original commit but it complains about permissions. Maybe I'm wrong but this seems very odd to me:
node = node->ultimate_alias_target ();

is basically referring to itself meaning:
if (callee->former_clone_of != node->decl
      && (node != node->ultimate_alias_target ())
      && !clone_of_p (node, callee))

the && (node != node->ultimate_alias_target ()) is basically referring to itself when comparing yet its already being defined equal to the return value of ultimate_alias_target meaning its always true. Not sure if this fixes this bug or something else. Thoughts?
Comment 18 Jakub Jelinek 2021-05-14 09:48:49 UTC
GCC 8 branch is being closed.
Comment 19 Richard Biener 2021-06-01 08:08:44 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 20 Richard Biener 2022-05-27 09:37:05 UTC
GCC 9 branch is being closed
Comment 21 Jakub Jelinek 2022-06-28 10:33:05 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 22 Richard Biener 2023-07-07 10:32:04 UTC
GCC 10 branch is being closed.