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
Confirmed. 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. > 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. This bug is breaking almost every non-trivial C++ project. It should be P1 IMO. Thus marking it as such. Even shorter: struct { const int i; } a[] = { 1 }; 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. 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 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. *** Bug 58966 has been marked as a duplicate of this bug. *** 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 |