Bug 58868

Summary: [4.9 Regression] ICE: in count_type_elements, at expr.c:5495 with -std=gnu++0x
Product: gcc Reporter: Ferdinand <ferdinandw+gcc>
Component: c++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: normal CC: dcb314, jason, octoploid, reichelt
Priority: P1 Keywords: ice-on-valid-code
Version: 4.9.0   
Target Milestone: 4.9.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2013-10-25 00:00:00

Description Ferdinand 2013-10-25 03:00:16 UTC
/opt/gcc-trunk/libexec/gcc/x86_64-redhat-linux/4.9.0/cc1plus -quiet -v TelemetryVFS.ii -O0 -g0 -std=gnu++0x -version -o TelemetryVFS.s

GNU C++ (GCC) version 4.9.0 20131025 (experimental) (x86_64-redhat-linux)
	compiled by GNU C version 4.9.0 20131025 (experimental), GMP version 5.1.1, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: e6bf66d0889337cd67d51ee6eb43d8c3
TelemetryVFS.ii:12:1: internal compiler error: in count_type_elements, at expr.c:5495
 };
 ^


../gcc/configure --prefix=/opt/gcc-trunk --enable-shared --enable-languages=c,c++ --enable-threads=posix --enable-checking --enable-__cxa_atexit --enable-clocale=gnu --enable-initfini-array --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --disable-nls --disable-multilib --with-system-zlib --build=x86_64-redhat-linux

====================================


enum ID {
  PLACES
};

struct Histograms {
  const ID foo;
};

Histograms gHistograms[] = {
  { PLACES }
};


====================================

Fairly recent, comes from building firefox aurora with gcc trunk
Comment 1 Marek Polacek 2013-10-25 05:44:23 UTC
Confirmed.
Comment 2 Marek Polacek 2013-10-25 06:56:00 UTC
Started with r203985.
Comment 3 Marek Polacek 2013-10-25 07:15:12 UTC
We somehow create 
    type <lang_type 0x7f62b24dcdc8 init list VOID
        align 1 symtab 0 alias set -1 canonical type 0x7f62b24dcdc8>
    constant lngt 1
and count_type_elements can't handle LANG_TYPE.
Comment 4 Trevor Saunders 2013-10-27 17:13:58 UTC
> enum ID {
>   PLACES
> };
> 
> struct Histograms {
>   const ID foo;

the enum isn't actually needed, I can reproduce with
static struct {
  const int type;
} const cnvNameType[] = {
  {  1 }
};

> Fairly recent, comes from building firefox aurora with gcc trunk

to be pedantic it is in icu, and presumably if you just build that you get this crash too.
Comment 5 Markus Trippelsdorf 2013-10-31 07:07:29 UTC
This bug is breaking almost every non-trivial C++ project.
It should be P1 IMO.
Comment 6 Marek Polacek 2013-10-31 07:09:54 UTC
Thus marking it as such.
Comment 7 Marek Polacek 2013-11-04 22:22:00 UTC
Even shorter:

struct { const int i; } a[] = { 1 };
Comment 8 Marek Polacek 2013-11-05 11:55:22 UTC
The issue, as I understand it, is that in check_initializer, in C++11 mode, we enter this block

      if ((type_build_ctor_call (type) || CLASS_TYPE_P (type))
          && !(flags & LOOKUP_ALREADY_DIGESTED)
          && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
               && CP_AGGREGATE_TYPE_P (type)
               && (CLASS_TYPE_P (type)
                   || type_has_extended_temps (type))))
        {

because type_build_ctor_call (type) is true in C++11, but false in C++03, and here we basically only set LOOKUP_ALREADY_DIGESTED.  Then later on in store_init_value we have

  if (flags & LOOKUP_ALREADY_DIGESTED)
    value = init;
  else 
    /* Digest the specified initializer into an expression.  */
    value = digest_init_flags (type, init, flags);

as a result, in C++11 "value" is {{1}}, while in C++03 {{.i=1}}.  In C++03, we save this into DECL_INITIAL and everything looks peachy, but in C++11 we call split_nonconstant_init and from there the things go wrong, I'd say.

I'm not clear on whether type_build_ctor_call should for struct s[1] return true or false.
It's also interesting why type_build_ctor_call returns false in C++03, it has this check

  if (cxx_dialect < cxx11)
    return false;

but that can be dropped and it still returns false.  The difference is in new hunk that came with r203985:

  /* A user-declared constructor might be private, and a constructor might
     be trivial but deleted.  */
  for (tree fns = lookup_fnfields_slot (inner, complete_ctor_identifier);
       fns; fns = OVL_NEXT (fns))
    {    
      tree fn = OVL_CURRENT (fns);
      debug_tree (fn);
      if (!DECL_ARTIFICIAL (fn) 
          || DECL_DELETED_FN (fn))
        return true;
    }

in C++03, there are two __comp_ctor's, in C++11 there are three __comp_ctor's, and the last one is DECL_DELETED_FN, thus we return true.  Why is that I have no clue whatsoever.

So, this all boils down to whether type_build_ctor_call is correct, or whether I should be looking for a bug elsewhere.
Comment 9 Jason Merrill 2013-11-05 18:03:05 UTC
Author: jason
Date: Tue Nov  5 18:03:03 2013
New Revision: 204406

URL: http://gcc.gnu.org/viewcvs?rev=204406&root=gcc&view=rev
Log:
	PR c++/58868
	* decl.c (check_initializer): Don't use build_vec_init for arrays
	of trivial type.

Added:
    trunk/gcc/testsuite/g++.dg/init/array35.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
Comment 10 Jason Merrill 2013-11-05 18:05:48 UTC
type_build_ctor_call is correct to return true here: the default constructor for Histograms is deleted in C++11 because it has a const member with no explicit initializer.

Fixed.
Comment 11 Volker Reichelt 2013-11-05 21:22:14 UTC
*** Bug 58966 has been marked as a duplicate of this bug. ***
Comment 12 Jason Merrill 2013-11-23 16:28:59 UTC
Author: jason
Date: Sat Nov 23 16:28:57 2013
New Revision: 205311

URL: http://gcc.gnu.org/viewcvs?rev=205311&root=gcc&view=rev
Log:
	PR c++/58868
	* init.c (build_aggr_init): Don't clobber the type of init
	if we got an INIT_EXPR back from build_vec_init.
	(build_vec_init): Do digest_init on trivial initialization.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/init.c