[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Andrew Pinski changed: What|Removed |Added CC||ejakobs at boerboeltrading dot com --- Comment #18 from Andrew Pinski --- *** Bug 109421 has been marked as a duplicate of this bug. ***
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #17 from CVS Commits --- The releases/gcc-12 branch has been updated by Jason Merrill : https://gcc.gnu.org/g:40f749b364b740f41ea6b211f81c21919a2e8bee commit r12-8380-g40f749b364b740f41ea6b211f81c21919a2e8bee Author: Jason Merrill Date: Fri May 13 16:07:10 2022 -0400 c++: array {}-init [PR105589] My patch for 105191 made us use build_value_init more frequently from build_vec_init_expr, but build_value_init doesn't like to be called to initialize a class in a template. That's caused trouble in the past, and seems like a strange restriction, so let's fix it. PR c++/105589 PR c++/105191 PR c++/92385 gcc/cp/ChangeLog: * init.cc (build_value_init): Handle class in template. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array16.C: New test.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #16 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:ce46d6041358052dfa26f3720732f0357c5d72e7 commit r13-463-gce46d6041358052dfa26f3720732f0357c5d72e7 Author: Jason Merrill Date: Fri May 13 16:07:10 2022 -0400 c++: array {}-init [PR105589] My patch for 105191 made us use build_value_init more frequently from build_vec_init_expr, but build_value_init doesn't like to be called to initialize a class in a template. That's caused trouble in the past, and seems like a strange restriction, so let's fix it. PR c++/105589 PR c++/105191 PR c++/92385 gcc/cp/ChangeLog: * init.cc (build_value_init): Handle class in template. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array16.C: New test.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #15 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:4822108e61ab879067482704f2f7d1670813d61a commit r12-8066-g4822108e61ab879067482704f2f7d1670813d61a Author: Jason Merrill Date: Fri Apr 8 15:33:41 2022 -0400 c++: constexpr non-trivial aggregate init [PR105191] My patch for PR92385 made us use VEC_INIT_EXPR for aggregate initialization of an array where some elements are not explicitly initialized. Constexpr handling of that was treating initialization from {} as equivalent to value-initialization, which is problematic for classes with default member initializers that make the default constructor non-trivial; in older standard modes, not initializing all members makes a constructor non-constexpr, but aggregate initialization is fine. PR c++/105191 PR c++/92385 gcc/cp/ChangeLog: * tree.cc (build_vec_init_elt): Do {}-init for aggregates. * constexpr.cc (cxx_eval_vec_init): Only treat {} as value-init for non-aggregate types. (build_vec_init_expr): Also check constancy of explicit initializer elements. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-array28.C: New test.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #14 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:119cea98f664764cce04963243c39c8f6d797d33 commit r12-7069-g119cea98f664764cce04963243c39c8f6d797d33 Author: Jason Merrill Date: Wed Feb 2 18:36:41 2022 -0500 c++: assignment, aggregate, array [PR104300] The PR92385 fix meant that we see more VEC_INIT_EXPR outside of INIT_EXPR; in such cases, we need to wrap them in TARGET_EXPR. I previously fixed that in build_array_copy; we also need it in process_init_constructor. After fixing that, I needed to adjust a few places to recognize the VEC_INIT_EXPR even inside a TARGET_EXPR. And prevent cp_fully_fold_init from lowering VEC_INIT_EXPR too soon. And handle COMPOUND_EXPR inside TARGET_EXPR better. PR c++/104300 PR c++/92385 gcc/cp/ChangeLog: * cp-tree.h (get_vec_init_expr): New. (target_expr_needs_replace): New. * cp-gimplify.cc (cp_gimplify_init_expr): Use it. (struct cp_fold_data): New. (cp_fold_r): Only genericize inits at end of fn. (cp_fold_function): Here. (cp_fully_fold_init): Not here. * init.cc (build_vec_init): Use get_vec_init_expr. * tree.cc (build_vec_init_expr): Likewise. * typeck2.cc (split_nonconstant_init_1): Likewise. (process_init_constructor): Wrap VEC_INIT_EXPR in TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array14.C: New test.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Jason Merrill changed: What|Removed |Added Target Milestone|--- |12.0 Known to work||12.0 Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #13 from Jason Merrill --- Fixed for GCC 12.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #12 from Jason Merrill --- *** Bug 65591 has been marked as a duplicate of this bug. ***
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Andrew Pinski changed: What|Removed |Added CC||gpkiwi at msn dot com --- Comment #11 from Andrew Pinski --- *** Bug 65503 has been marked as a duplicate of this bug. ***
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Andrew Pinski changed: What|Removed |Added CC||gnu at kosak dot com --- Comment #10 from Andrew Pinski --- *** Bug 87680 has been marked as a duplicate of this bug. ***
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #9 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:e948436eab818c527dd60b0ef939c4f42fbe8ba4 commit r12-6326-ge948436eab818c527dd60b0ef939c4f42fbe8ba4 Author: Jason Merrill Date: Sat Jan 1 16:00:09 2022 -0500 c++: loop over array elts w/o explicit init [PR92385] The PR complains that initializing a large array with {} takes a long time to compile; this was because digest_init would turn {} into a long CONSTRUCTOR with an initializer for each element, instead of more sensibly generating a loop. The standard doesn't specify this implementation, but it does allow for it by specifying that a temporary created "when a default constructor is called to initialize an element of an array with no corresponding initializer" is destroyed "before the construction of the next array element, if any." rather than living until the end of the complete object initialization as usual. This change is also needed before the PR94041 fix extends the lifetime of temporaries from elements with explicit initializers. To implement this, I change digest_init so that in cases where initialization of trailing array elements isn't constant, we return a VEC_INIT_EXPR instead of a bare CONSTRUCTOR; when it is encountered later, we call build_vec_init to generate the actual initialization code. PR c++/92385 gcc/cp/ChangeLog: * typeck2.c (PICFLAG_VEC_INIT): New. (process_init_constructor_array): Set it. (process_init_constructor): Handle it. (split_nonconstant_init_1): Handle VEC_INIT_EXPR. * init.c (build_vec_init): Likewise. * cp-gimplify.c (cp_gimplify_expr): Factor out... * tree.c (expand_vec_init_expr): ...this function. (build_vec_init_elt): Handle BRACE_ENCLOSED_INITIALIZER_P. (build_vec_init_expr): Likewise. * constexpr.c (cxx_eval_vec_init): Likewise. (reduced_constant_expression_p): Check arrays before C++20. * cp-tree.h (expand_vec_init_expr): Declare. gcc/testsuite/ChangeLog: * g++.dg/init/array61.C: New test.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Jason Merrill changed: What|Removed |Added CC||jason at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |jason at gcc dot gnu.org Status|NEW |ASSIGNED
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Andrew Pinski changed: What|Removed |Added CC||beyondstandard at gmail dot com --- Comment #8 from Andrew Pinski --- *** Bug 71165 has been marked as a duplicate of this bug. ***
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Andrew Pinski changed: What|Removed |Added CC||hehaochen at hotmail dot com --- Comment #7 from Andrew Pinski --- *** Bug 94957 has been marked as a duplicate of this bug. ***
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #6 from Carl --- > I'm not sure if () and {} are semantically equivalent [in this case]. For what it's worth, (not sure if I'm allowed to paste a link here, but) on cppreference.com [1] under "Constructors and member initializer lists", it describes the following forms for "member-initializers" in "the body of a function definition of any constructor" : class-or-identifier ( expression-list(optional) ) (1) class-or-identifier brace-init-list (2) (since C++11) And about these it says: 1) Initializes the base or member named by class-or-identifier using direct initialization or, if expression-list is empty, value-initialization 2) Initializes the base or member named by class-or-identifier using list-initialization (which becomes value-initialization if the list is empty and aggregate-initialization when initializing an aggregate) So it seems in this case of "a()" (1) vs "a{}" (2), either one results in "value-initialization", which is further described here [2]. The following forms are described for value-initialization: T() (1) T{} (5) (since C++11) About which it says: 1,5) when a nameless temporary object is created with the initializer consisting of an empty pair of parentheses [or braces (since C++11)]; But then it goes on to say: In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization. (And notably, an array is an aggregate type.) Then the page on aggregate-initialization[3] goes on to describe the many semantic effects of aggregate initialization... The part that seems to apply is If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are initialized by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates). (since C++11) I presume our "struct item" counts as a "non-aggregate class with default constructor", which would result in value-initialization, but my lawyer glasses are a little fuzzy here. Whereas, the way I read the value-initialization rules, if "()" is used (that is, not "the empty pair of braces {}"), then this rule applies: 3) if T is an array type, each element of the array is value-initialized; Which means that for every element of the array this applies: 1) if T is a class type with [...] a user-provided [...] constructor, the object is default-initialized; So, a bit round-about, but it seems like both routes would result in value-initialization, which ends up meaning each element gets default-initialized. But you have to squint real hard, and the rules about how to get there seem to follow surprisingly different-looking paths... Maybe that (partially) explains the different code-paths in g++. Carl [1] https://en.cppreference.com/w/cpp/language/initializer_list [2] https://en.cppreference.com/w/cpp/language/value_initialization [3] https://en.cppreference.com/w/cpp/language/aggregate_initialization
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #5 from Richard Biener --- Whereas with (): ;; Function item_array::item_array() (null) ;; enabled by -tree-original <; { >>) >; } I'm not sure if () and {} are semantically equivalent [in this case].
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 Richard Biener changed: What|Removed |Added Keywords||compile-time-hog, ||memory-hog Status|UNCONFIRMED |NEW Last reconfirmed||2019-11-06 Ever confirmed|0 |1 --- Comment #4 from Richard Biener --- It's yet another case where the C++ FE should emit loops rather than individual array element initializations. ;; Function item_array::item_array() (null) ;; enabled by -tree-original <; { > , TARGET_EXPR >> , TARGET_EXPR >> , TARGET_EXPR >> }) >; also probably not too intelligent individual elements either.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #3 from Carl --- Original "good.cpp" and "bad.cpp" sources now attached.
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #2 from Carl --- Created attachment 47181 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47181=edit source that does not exhibit bad compilation performance Note the constructor initializes the member with parens: "item_array() : a() {}"
[Bug c++/92385] extremely long and memory intensive compilation for brace construction of array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385 --- Comment #1 from Carl --- Created attachment 47179 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47179=edit original source file with bad compilation performance Note the brace member initialization in the constructor: "item_array() : a{} {}"