Bug 87554 - [8 Regression] internal compiler error: in record_reference, at cgraphbuild.c:64
Summary: [8 Regression] internal compiler error: in record_reference, at cgraphbuild.c:64
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.2.0
: P2 normal
Target Milestone: 8.4
Assignee: Jason Merrill
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2018-10-08 14:03 UTC by Mykhailo Kremniov
Modified: 2020-02-26 17:55 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.3.0
Known to fail: 8.1.0, 8.2.1
Last reconfirmed: 2018-10-08 00:00:00


Attachments
Preprocessed source (243.02 KB, application/gzip)
2018-10-08 14:05 UTC, Mykhailo Kremniov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mykhailo Kremniov 2018-10-08 14:03:21 UTC
GCC crashes when compiling the attached file with -O1
==
$ g++-8.2.0 -v
Using built-in specs.
COLLECT_GCC=g++-8.2.0
COLLECT_LTO_WRAPPER=/home/brd/soft/gcc-8.2.0/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ./configure --prefix=/home/brd/soft/gcc-8.2.0
Thread model: posix
gcc version 8.2.0 (GCC)

$ g++-8.2.0 -O1 -c test.cpp.i -o test.o
cc1plus: internal compiler error: in record_reference, at cgraphbuild.c:64
0x59361b record_reference
	../.././gcc/cgraphbuild.c:64
0xd8aad3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*))
	../.././gcc/tree.c:11396
0xd8af7a walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*))
	../.././gcc/tree.c:11712
0x7e1bf6 record_references_in_initializer(tree_node*, bool)
	../.././gcc/cgraphbuild.c:386
0xdbd406 varpool_node::analyze()
	../.././gcc/varpool.c:534
0x7e5fbe analyze_functions
	../.././gcc/cgraphunit.c:1185
0x7e6c72 symbol_table::finalize_compilation_unit()
	../.././gcc/cgraphunit.c:2691
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
==
Comment 1 Mykhailo Kremniov 2018-10-08 14:05:41 UTC
Created attachment 44808 [details]
Preprocessed source
Comment 2 Richard Biener 2018-10-08 14:33:55 UTC
Confirmed.  GCC 7 doesn't like the preprocessed source so no idea if a regression.
Comment 3 Mykhailo Kremniov 2018-10-08 15:05:33 UTC
FYI: 6.3.0 is able to compile the non-preprocessed source.

As for 7.x - 7.3.0 and earlier versions can't compile it due to another bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85470) and I don't have 7.4 at hand.
Comment 4 Martin Liška 2018-10-09 07:11:27 UTC
I'm reducing that ...
Comment 5 Martin Liška 2018-10-09 07:39:29 UTC
Reduced test-case:

$ cat pr87554.ii
template < class a > class b {
  static void c(a);
  static a &create() { c(instance); return mya; }

  static a mya;

public:
  static a d() { create(); return a(); }
  static a &instance;
};
template < class a > a &b< a >::instance = create();
class e;
class f {
public:
  void operator()(int g) { h(g); }
  template < class a > void h(a i) { p(j, i); }
  e *j;
};
class e : public f {
public:
  e(int);
};
struct k {
  int l;
};
template < class m, class a > void p(m, a) { b< k >::d(); }
extern template class b< k >;
int n;
int o;
void test() {
  e out(o);
  out(n);
}

Started with r259571.
Comment 6 Martin Liška 2019-01-03 09:57:16 UTC
With first bad revision the constructor looks as follows:

$ (gdb) p print_generic_expr(stderr, decl->decl_common.initial, 0)
instance = b<k>::create ()$1 = void
(gdb) p debug_tree(decl->decl_common.initial)
 <init_expr 0x7ffff6cc0a50
    type <reference_type 0x7ffff6cbe540
        type <record_type 0x7ffff6cb5f18 k type_5 type_6 SI
            size <integer_cst 0x7ffff6b730c0 constant 32>
            unit-size <integer_cst 0x7ffff6b730d8 constant 4>
            align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6cb5f18 fields <function_decl 0x7ffff6cc8700 __ct > context <translation_unit_decl 0x7ffff6b60168 /home/marxin/Programming/testcases/pr87554.ii>
            full-name "struct k"
            X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown
            pointer_to_this <pointer_type 0x7ffff6cbe9d8> reference_to_this <reference_type 0x7ffff6cbe540> chain <type_decl 0x7ffff6c7bda8 k>>
        unsigned DI
        size <integer_cst 0x7ffff6b53e70 constant 64>
        unit-size <integer_cst 0x7ffff6b53e88 constant 8>
        align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6cbe540>
    side-effects
    arg:0 <var_decl 0x7ffff6cbd2d0 instance type <reference_type 0x7ffff6cbe540>
        readonly used public static tree_1 tree_3 unsigned external nonlocal read decl_3 decl_5 DI /home/marxin/Programming/testcases/pr87554.ii:11:25 size <integer_cst 0x7ffff6b53e70 64> unit-size <integer_cst 0x7ffff6b53e88 8>
        align:64 warn_if_not_align:0 context <record_type 0x7ffff6cbe348 b> initial <init_expr 0x7ffff6cc0a50>
        template-info 0x7ffff6ca6f20
        chain <type_decl 0x7ffff6cbf1c8 b type <record_type 0x7ffff6cbe3f0 b>
            external nonlocal suppress-debug decl_4 VOID /home/marxin/Programming/testcases/pr87554.ii:1:30
            align:8 warn_if_not_align:0 context <record_type 0x7ffff6cbe348 b> result <record_type 0x7ffff6cbe348 b>
           >>
    arg:1 <call_expr 0x7ffff6cca090 type <reference_type 0x7ffff6cbe540>
        side-effects
        fn <addr_expr 0x7ffff6cc2e40 type <pointer_type 0x7ffff6cc47e0>
            constant arg:0 <function_decl 0x7ffff6cc1000 create>>
        /home/marxin/Programming/testcases/pr87554.ii:11:50 start: /home/marxin/Programming/testcases/pr87554.ii:11:44 finish: /home/marxin/Programming/testcases/pr87554.ii:11:51>>

before that C++ FE reported following error:

$ ./xgcc -B. ~/Programming/testcases/pr87554.ii -c -O2
/home/marxin/Programming/testcases/pr87554.ii: In instantiation of ‘k& b<k>::instance’:
/home/marxin/Programming/testcases/pr87554.ii:3:26:   required from ‘static a& b<a>::create() [with a = k]’
/home/marxin/Programming/testcases/pr87554.ii:8:24:   required from ‘static a b<a>::d() [with a = k]’
/home/marxin/Programming/testcases/pr87554.ii:26:55:   required from ‘void p(m, a) [with m = e*; a = int]’
/home/marxin/Programming/testcases/pr87554.ii:16:39:   required from ‘void f::h(a) [with a = int]’
/home/marxin/Programming/testcases/pr87554.ii:15:31:   required from here
/home/marxin/Programming/testcases/pr87554.ii:11:50: error: call to non-‘constexpr’ function ‘static a& b<a>::create() [with a = k]’
 template < class a > a &b< a >::instance = create();
                                            ~~~~~~^~

Jason can you please take a look?
Comment 7 Jakub Jelinek 2019-02-22 15:21:47 UTC
GCC 8.3 has been released.
Comment 8 Jan Hubicka 2019-04-11 11:59:39 UTC
The constructor indeed looks broken to me: it should not have naked var_decl. So I am changing component to C++
Comment 9 Jason Merrill 2019-04-18 16:50:42 UTC
Author: jason
Date: Thu Apr 18 16:50:10 2019
New Revision: 270445

URL: https://gcc.gnu.org/viewcvs?rev=270445&root=gcc&view=rev
Log:
	PR c++/87554 - ICE with extern template and reference member.

The removed code ended up setting DECL_INITIAL to the INIT_EXPR returned by
split_nonconstant_init, which makes no sense.  This code was added back in
1996, so any rationale is long lost.

	* decl.c (cp_finish_decl): Don't set DECL_INITIAL of external vars.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/extern_template-5.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
Comment 10 Jason Merrill 2019-04-18 17:12:58 UTC
(In reply to Jan Hubicka from comment #8)
> The constructor indeed looks broken to me: it should not have naked
> var_decl. So I am changing component to C++

I agree that the C++ front end is wrong here, but I also wonder why cgraph is looking at the DECL_INITIAL of a DECL_EXTERNAL variable.
Comment 11 Jan Hubicka 2019-04-18 17:16:15 UTC
> > The constructor indeed looks broken to me: it should not have naked
> > var_decl. So I am changing component to C++
> 
> I agree that the C++ front end is wrong here, but I also wonder why cgraph is
> looking at the DECL_INITIAL of a DECL_EXTERNAL variable.

Well, at least for constant variables those are useful for contant
folding.  But I suppose we may take care to get rid of decl initials
of non-readonly externals somewhere soon (we do it eventually as part
of unreachable code removal)

Honza
> 
> -- 
> You are receiving this mail because:
> You are on the CC list for the bug.
Comment 12 GCC Commits 2020-02-26 04:55:00 UTC
The releases/gcc-8 branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:a57528b33be33d4428ac62901d04cf39807d624e

commit r8-10074-ga57528b33be33d4428ac62901d04cf39807d624e
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Feb 25 13:37:18 2020 -0500

    PR c++/87554 - ICE with extern template and reference member.
    
    The removed code ended up setting DECL_INITIAL to the INIT_EXPR returned by
    split_nonconstant_init, which makes no sense.  This code was added back in
    1996, so any rationale is long lost.
    
    gcc/cp/ChangeLog
    2020-02-25  Jason Merrill  <jason@redhat.com>
    
    	PR c++/87554 - ICE with extern template and reference member.
    	* decl.c (cp_finish_decl): Don't set DECL_INITIAL of external vars.
Comment 13 Jason Merrill 2020-02-26 17:55:37 UTC
Fixed for 8.4.