aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.cc
AgeCommit message (Collapse)AuthorFilesLines
2024-07-10c++: array new with value-initialization [PR115645]Marek Polacek1-4/+8
This extends the r11-5179 fix which doesn't work with multidimensional arrays. In particular, struct S { explicit S() { } }; auto p = new S[1][1](); should not say "converting to S from initializer list would use explicit constructor" because there's no {}. However, since we went into the block where we create a {}, we got confused. We should not have gotten there but we did because array_p was true. This patch refines the check once more. PR c++/115645 gcc/cp/ChangeLog: * init.cc (build_new): Don't do any deduction for arrays with bounds if it's value-initialized. gcc/testsuite/ChangeLog: * g++.dg/expr/anew7.C: New test.
2024-07-02c++: Implement C++26 P3144R2 - Deleting a Pointer to an Incomplete Type ↵Jakub Jelinek1-2/+36
Should be Ill-formed [PR115747] The following patch implements the C++26 paper which makes delete and delete[] on incomplete class types invalid, previously it has been UB unless the class had trivial destructor and no custom deallocator. The patch uses permerror_opt, so -Wno-delete-incomplete makes it still compile without warnings like before, and -fpermissive makes it warn but not error; in SFINAE contexts it is considered an error in C++26 and later. 2024-07-02 Jakub Jelinek <jakub@redhat.com> Jason Merrill <jason@redhat.com> PR c++/115747 gcc/cp/ * init.cc: Implement C++26 P3144R2 - Deleting a Pointer to an Incomplete Type Should be Ill-formed. (build_vec_delete_1): Emit permerror_at and return error_mark_node for delete [] on incomplete type. (build_delete): Similarly for delete. gcc/testsuite/ * g++.dg/init/delete1.C: Adjust expected diagnostics for C++26. * g++.dg/warn/Wdelete-incomplete-1.C: Likewise. * g++.dg/warn/incomplete1.C: Likewise. * g++.dg/ipa/pr85607.C: Likewise. * g++.dg/cpp26/delete1.C: New test. * g++.dg/cpp26/delete2.C: New test. * g++.dg/cpp26/delete3.C: New test.
2024-05-28c++: extend -Wself-move for mem-init-list [PR109396]Marek Polacek1-2/+3
We already warn for: x = std::move (x); which triggers: warning: moving 'x' of type 'int' to itself [-Wself-move] but bug 109396 reports that this doesn't work for a member-initializer-list: X() : x(std::move (x)) so this patch amends that. PR c++/109396 gcc/cp/ChangeLog: * cp-tree.h (maybe_warn_self_move): Declare. * init.cc (perform_member_init): Call maybe_warn_self_move. * typeck.cc (maybe_warn_self_move): No longer static. Change the return type to bool. Also warn when called from a member-initializer-list. Drop the inform call. gcc/testsuite/ChangeLog: * g++.dg/warn/Wself-move2.C: New test.
2024-05-23c++: deleting array temporary [PR115187]Jason Merrill1-1/+8
Decaying the array temporary to a pointer and then deleting that crashes in verify_gimple_stmt, because the TARGET_EXPR is first evaluated inside the TRY_FINALLY_EXPR, but the cleanup point is outside. Fixed by using get_target_expr instead of save_expr. I also adjust the stabilize_expr comment to prevent me from again thinking it's a suitable replacement. PR c++/115187 gcc/cp/ChangeLog: * init.cc (build_delete): Use get_target_expr instead of save_expr. * tree.cc (stabilize_expr): Update comment. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/array-prvalue3.C: New test.
2024-05-14c++ comment adjustments for 114935Jason Merrill1-2/+8
gcc/cp/ChangeLog: * decl.cc (wrap_cleanups_r): Clarify comment. * init.cc (build_vec_init): Update comment.
2024-05-08c++/modules: Stream unmergeable temporaries by value again [PR114856]Nathaniel Shead1-1/+1
In r14-9266-g2823b4d96d9ec4 I gave all temporary vars a DECL_CONTEXT, including those at namespace or global scope, so that they could be properly merged across importers. However, not all of these temporary vars are actually supposed to be mergeable. For instance, in the attached testcase we have an unnamed temporary var used in the NSDMI of a class member, which cannot properly merged -- but it also doesn't need to be, as it'll be thrown away when the class type itself is merged anyway. This patch reverts the change made above and instead makes a weaker adjustment that only causes temporary vars with linkage have a DECL_CONTEXT to merge from. This way these unnamed, "unmergeable" temporaries are properly streamed by value again. PR c++/114856 gcc/cp/ChangeLog: * call.cc (make_temporary_var_for_ref_to_temp): Set context for temporaries with linkage. * init.cc (create_temporary_var): Revert to only set context when in a function decl. gcc/testsuite/ChangeLog: * g++.dg/modules/pr114856.h: New test. * g++.dg/modules/pr114856_a.H: New test. * g++.dg/modules/pr114856_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com> Reviewed-by: Patrick Palka <ppalka@redhat.com>
2024-05-07c++: DECL_DECOMPOSITION_P cleanupMarek Polacek1-1/+1
DECL_DECOMPOSITION_P already checks VAR_P but we repeat the check in a lot of places. gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Don't check VAR_P before DECL_DECOMPOSITION_P. * init.cc (build_aggr_init): Likewise. * parser.cc (cp_parser_range_for): Likewise. (do_range_for_auto_deduction): Likewise. (cp_convert_range_for): Likewise. (cp_convert_omp_range_for): Likewise. (cp_finish_omp_range_for): Likewise. * pt.cc (extract_locals_r): Likewise. (tsubst_omp_for_iterator): Likewise. (tsubst_decomp_names): Likewise. (tsubst_stmt): Likewise. * typeck.cc (maybe_warn_about_returning_address_of_local): Likewise.
2024-03-25c++: broken direct-init with trailing array member [PR114439]Marek Polacek1-1/+5
can_init_array_with_p is wrongly saying that the init for 's' here: struct S { int *list = arr; int arr[]; }; struct A { A() {} S s[2]{}; }; is invalid. But as process_init_constructor_array says, for "non-constant initialization of trailing elements with no explicit initializers" we use a VEC_INIT_EXPR wrapped in a TARGET_EXPR, built in process_init_constructor. Unfortunately we didn't have a test for this scenario so I didn't realize can_init_array_with_p must handle it. PR c++/114439 gcc/cp/ChangeLog: * init.cc (can_init_array_with_p): Return true for a VEC_INIT_EXPR wrapped in a TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/init/array65.C: New test.
2024-03-22c++: direct-init of an array of class type [PR59465]Marek Polacek1-3/+28
...from another array in a mem-initializer should not be accepted. We already reject struct string {} a[1]; string x[1](a); but struct pair { string s[1]; pair() : s(a) {} }; is wrongly accepted. It started to be accepted with r0-110915-ga034826198b771: <https://gcc.gnu.org/pipermail/gcc-patches/2011-August/320236.html> which was supposed to be a cleanup, not a deliberate change to start accepting the code. The build_vec_init_expr code was added in r165976: <https://gcc.gnu.org/pipermail/gcc-patches/2010-October/297582.html>. It appears that we do the magic copy array when we have a defaulted constructor and we generate code for its mem-initializer which initializes an array. I also see that we go that path for compound literals. So when initializing an array member, we can limit building up a VEC_INIT_EXPR to those special cases. PR c++/59465 gcc/cp/ChangeLog: * init.cc (can_init_array_with_p): New. (perform_member_init): Check it. gcc/testsuite/ChangeLog: * g++.dg/init/array62.C: New test. * g++.dg/init/array63.C: New test. * g++.dg/init/array64.C: New test.
2024-03-02c++: Ensure DECL_CONTEXT is set for temporary vars [PR114005]Nathaniel Shead1-1/+1
Modules streaming requires DECL_CONTEXT to be set for anything streamed. This patch ensures that 'create_temporary_var' does set a DECL_CONTEXT for these variables (such as the backing storage for initializer_lists) even if not inside a function declaration. PR c++/114005 gcc/cp/ChangeLog: * init.cc (create_temporary_var): Use current_scope instead of current_function_decl. gcc/testsuite/ChangeLog: * g++.dg/modules/pr114005_a.C: New test. * g++.dg/modules/pr114005_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2024-02-29c++: -Wuninitialized when binding a ref to uninit DM [PR113987]Marek Polacek1-1/+2
This PR asks that our -Wuninitialized for mem-initializers does not warn when binding a reference to an uninitialized data member. We already check !INDIRECT_TYPE_P in find_uninit_fields_r, but that won't catch binding a parameter of a reference type to an uninitialized field, as in: struct S { S (int&); }; struct T { T() : s(i) {} S s; int i; }; This patch adds a new function to handle this case. PR c++/113987 gcc/cp/ChangeLog: * call.cc (conv_binds_to_reference_parm_p): New. * cp-tree.h (conv_binds_to_reference_parm_p): Declare. * init.cc (find_uninit_fields_r): Call it. gcc/testsuite/ChangeLog: * g++.dg/warn/Wuninitialized-15.C: Turn dg-warning into dg-bogus. * g++.dg/warn/Wuninitialized-34.C: New test.
2024-01-25c++: array of PMF [PR113598]Jason Merrill1-1/+3
Here AGGREGATE_TYPE_P includes pointers to member functions, which is not what we want. Instead we should use class||array, as elsewhere in the function. PR c++/113598 gcc/cp/ChangeLog: * init.cc (build_vec_init): Don't use {} for PMF. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-pmf2.C: New test.
2024-01-15c++: non-dep array list-init w/ non-triv dtor [PR109899]Patrick Palka1-1/+2
The get_target_expr call added in r12-7069-g119cea98f66476 causes us for the below testcase to call build_vec_delete in a template context, which builds a templated destructor call and checks expr_noexcept_p for it, which ICEs because the call has templated form. Much of the work of build_vec_delete however is code generation and thus will just get discarded in a template context, and that includes the code guarded by expr_noexcept_p. So this patch narrowly fixes this ICE by eliding the expr_noexcept_p call when in a template context. PR c++/109899 gcc/cp/ChangeLog: * init.cc (build_vec_delete_1): Assume expr_noexcept_p returns false in a template context. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array21.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
2024-01-09c++: P0847R7 (deducing this) - prerequisite changes. [PR102609]waffl3x1-2/+2
Adds the xobj_flag member to lang_decl_fn and a corresponding member access macro and predicate to support the addition of explicit object member functions. Additionally, since explicit object member functions are also non-static member functions, we need to change uses of DECL_NONSTATIC_MEMBER_FUNCTION_P to clarify whether they intend to include or exclude them. PR c++/102609 gcc/cp/ChangeLog: * cp-tree.h (struct lang_decl_fn): New data member. (DECL_NONSTATIC_MEMBER_FUNCTION_P): Poison. (DECL_IOBJ_MEMBER_FUNCTION_P): Define. (DECL_FUNCTION_XOBJ_FLAG): Define. (DECL_XOBJ_MEMBER_FUNCTION_P): Define. (DECL_OBJECT_MEMBER_FUNCTION_P): Define. (DECL_FUNCTION_MEMBER_P): Don't use DECL_NONSTATIC_MEMBER_FUNCTION_P. (DECL_CONST_MEMFUNC_P): Likewise. (DECL_VOLATILE_MEMFUNC_P): Likewise. (DECL_NONSTATIC_MEMBER_P): Likewise. * module.cc (trees_out::lang_decl_bools): Handle xobj_flag. (trees_in::lang_decl_bools): Handle xobj_flag. * call.cc (build_this_conversion) (add_function_candidate) (add_template_candidate_real) (add_candidates) (maybe_warn_class_memaccess) (cand_parms_match) (joust) (do_warn_dangling_reference) * class.cc (finalize_literal_type_property) (finish_struct) (resolve_address_of_overloaded_function) * constexpr.cc (is_valid_constexpr_fn) (cxx_bind_parameters_in_call) * contracts.cc (build_contract_condition_function) * cp-objcp-common.cc (cp_decl_dwarf_attribute) * cxx-pretty-print.cc (cxx_pretty_printer::postfix_expression) (cxx_pretty_printer::declaration_specifiers) (cxx_pretty_printer::direct_declarator) * decl.cc (cp_finish_decl) (grok_special_member_properties) (start_preparsed_function) (record_key_method_defined) * decl2.cc (cp_handle_deprecated_or_unavailable) * init.cc (find_uninit_fields_r) (build_offset_ref) * lambda.cc (lambda_expr_this_capture) (maybe_generic_this_capture) (nonlambda_method_basetype) * mangle.cc (write_nested_name) * method.cc (early_check_defaulted_comparison) (skip_artificial_parms_for) (num_artificial_parms_for) * pt.cc (is_specialization_of_friend) (determine_specialization) (copy_default_args_to_explicit_spec) (check_explicit_specialization) (tsubst_contract_attribute) (check_non_deducible_conversions) (more_specialized_fn) (maybe_instantiate_noexcept) (register_parameter_specializations) (value_dependent_expression_p) * search.cc (shared_member_p) (lookup_member) (field_access_p) * semantics.cc (finish_omp_declare_simd_methods) * tree.cc (lvalue_kind) * typeck.cc (invalid_nonstatic_memfn_p): Don't use DECL_NONSTATIC_MEMBER_FUNCTION_P. libcc1/ChangeLog: * libcp1plugin.cc (plugin_pragma_push_user_expression): Don't use DECL_NONSTATIC_MEMBER_FUNCTION_P. Signed-off-by: Waffl3x <waffl3x@protonmail.com> Co-authored-by: Jason Merrill <jason@redhat.com>
2024-01-03Update copyright years.Jakub Jelinek1-1/+1
2023-10-27c++: another build_new_1 folding fix [PR111929]Patrick Palka1-4/+4
In build_new_1, we also need to avoid folding 'outer_nelts_check' when in a template context to prevent an ICE on the below testcase. This patch replaces the problematic fold_build2 call with build2 (we'll later fold it if appropriate during cp_fully_fold). In passing, this patch removes an unnecessary conversion of 'nelts' since it should always already be a size_t (and 'convert' isn't the best conversion entry point to use anyway since it lacks a complain parameter). PR c++/111929 gcc/cp/ChangeLog: * init.cc (build_new_1): Remove unnecessary call to convert on 'nelts'. Use build2 instead of fold_build2 for 'outer_nelts_checks'. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent28a.C: New test.
2023-10-24c++: non-dep array new-expr size [PR111929]Patrick Palka1-4/+5
This PR is another instance of NON_DEPENDENT_EXPR having acted as an "analysis barrier" for middle-end routines, and now that it's gone we're more prone to passing weird templated trees (that have a generic tree code) to middle-end routines which end up ICEing on such trees. In the testcase below the non-dependent array new-expr size 'x + 42' is expressed as an ordinary PLUS_EXPR, but whose operands have different types (since templated trees encode just the syntactic form of an expression devoid of e.g. implicit conversions). This type incoherency triggers an ICE from size_binop in build_new_1 due to a wide_int assert that expects the operand types to have the same precision. This patch fixes this by replacing our piecemeal folding of 'size' in build_new_1 with a single call to cp_fully_fold (which is a no-op in a template context) once 'size' is built up. PR c++/111929 gcc/cp/ChangeLog: * init.cc (build_new_1): Use convert, build2, build3 and cp_fully_fold instead of fold_convert, size_binop and fold_build3 when building up 'size'. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent28.C: New test.
2023-10-20c++: rename tsubst_copy_and_build and tsubst_exprPatrick Palka1-2/+1
After the previous patch, we now only have two tsubst entry points for expression trees: tsubst_copy_and_build and tsubst_expr. The former despite its unwieldy name is the main entry point, and the latter is just a superset of the former that also handles statement trees. We could merge them so that we just have tsubst_expr, but it seems natural to distinguish statement trees from expression trees and to maintain a separate entry point for them. To that end, this this patch renames tsubst_copy_and_build to tsubst_expr, and renames the current tsubst_expr to tsubst_stmt, which continues to be a superset of the former (which is convenient since sometimes expression trees appear in statement contexts, e.g. a branch of an IF_STMT could be NOP_EXPR). (Making tsubst_stmt disjoint from tsubst_expr is left as future work if deemed desirable.) This patch in turn renames suitable existing uses of tsubst_expr (that expect to take statement trees) to use tsubst_stmt. Thus untouched tsubst_expr calls are implicitly strengthened to expect only expression trees after this patch. For the tsubst_omp_* routines I opted to rename all existing uses to ensure no unintended functional change. This patch also moves the handling of CO_YIELD_EXPR and CO_AWAIT_EXPR from tsubst_stmt to tsubst_expr since they're indeed expression trees. gcc/cp/ChangeLog: * cp-lang.cc (objcp_tsubst_copy_and_build): Rename to ... (objcp_tsubst_expr): ... this. * cp-objcp-common.h (objcp_tsubst_copy_and_build): Rename to ... (objcp_tsubst_expr): ... this. * cp-tree.h (tsubst_copy_and_build): Remove declaration. * init.cc (maybe_instantiate_nsdmi_init): Use tsubst_expr instead of tsubst_copy_and_build. * pt.cc (expand_integer_pack): Likewise. (instantiate_non_dependent_expr_internal): Likewise. (instantiate_class_template): Use tsubst_stmt instead of tsubst_expr for STATIC_ASSERT. (tsubst_function_decl): Adjust tsubst_copy_and_build uses. (tsubst_arg_types): Likewise. (tsubst_exception_specification): Likewise. (tsubst_tree_list): Likewise. (tsubst): Likewise. (tsubst_name): Likewise. (tsubst_omp_clause_decl): Use tsubst_stmt instead of tsubst_expr. (tsubst_omp_clauses): Likewise. (tsubst_copy_asm_operands): Adjust tsubst_copy_and_build use. (tsubst_omp_for_iterator): Use tsubst_stmt instead of tsubst_expr. (tsubst_expr): Rename to ... (tsubst_stmt): ... this. <case CO_YIELD_EXPR, CO_AWAIT_EXPR>: Move to tsubst_expr. (tsubst_omp_udr): Use tsubst_stmt instead of tsubst_expr. (tsubst_non_call_postfix_expression): Adjust tsubst_copy_and_build use. (tsubst_lambda_expr): Likewise. Use tsubst_stmt instead of tsubst_expr for the body of a lambda. (tsubst_copy_and_build_call_args): Rename to ... (tsubst_call_args): ... this. Adjust tsubst_copy_and_build use. (tsubst_copy_and_build): Rename to tsubst_expr. Adjust tsubst_copy_and_build and tsubst_copy_and_build_call_args use. <case TRANSACTION_EXPR>: Use tsubst_stmt instead of tsubst_expr. (maybe_instantiate_noexcept): Adjust tsubst_copy_and_build use. (instantiate_body): Use tsubst_stmt instead of tsubst_expr for substituting the function body. (tsubst_initializer_list): Adjust tsubst_copy_and_build use. gcc/objcp/ChangeLog: * objcp-lang.cc (objcp_tsubst_copy_and_build): Rename to ... (objcp_tsubst_expr): ... this. Adjust tsubst_copy_and_build uses. Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-20c++: remove NON_DEPENDENT_EXPR, part 2Patrick Palka1-5/+0
This follow-up patch removes build_non_dependent_expr (and make_args_non_dependent) and calls thereof, no functional change. gcc/cp/ChangeLog: * call.cc (build_new_method_call): Remove calls to build_non_dependent_expr and/or make_args_non_dependent. * coroutines.cc (finish_co_return_stmt): Likewise. * cp-tree.h (build_non_dependent_expr): Remove. (make_args_non_dependent): Remove. * decl2.cc (grok_array_decl): Remove calls to build_non_dependent_expr and/or make_args_non_dependent. (build_offset_ref_call_from_tree): Likewise. * init.cc (build_new): Likewise. * pt.cc (make_args_non_dependent): Remove. (test_build_non_dependent_expr): Remove. (cp_pt_cc_tests): Adjust. * semantics.cc (finish_expr_stmt): Remove calls to build_non_dependent_expr and/or make_args_non_dependent. (finish_for_expr): Likewise. (finish_call_expr): Likewise. (finish_omp_atomic): Likewise. * typeck.cc (finish_class_member_access_expr): Likewise. (build_x_indirect_ref): Likewise. (build_x_binary_op): Likewise. (build_x_array_ref): Likewise. (build_x_vec_perm_expr): Likewise. (build_x_shufflevector): Likewise. (build_x_unary_op): Likewise. (cp_build_addressof): Likewise. (build_x_conditional_expr): Likewise. (build_x_compound_expr): Likewise. (build_static_cast): Likewise. (build_x_modify_expr): Likewise. (check_return_expr): Likewise. * typeck2.cc (build_x_arrow): Likewise. Reviewed-by: Jason Merrill <jason@redhat.com>
2023-08-04frontend: Add novector C++ pragmaTamar Christina1-1/+1
FORTRAN currently has a pragma NOVECTOR for indicating that vectorization should not be applied to a particular loop. ICC/ICX also has such a pragma for C and C++ called #pragma novector. As part of this patch series I need a way to easily turn off vectorization of particular loops, particularly for testsuite reasons. This patch proposes a #pragma GCC novector that does the same for C++ as gfortan does for FORTRAN and what ICX/ICX does for C++. I added only some basic tests here, but the next patch in the series uses this in the testsuite in about ~800 tests. gcc/cp/ChangeLog: * cp-tree.h (RANGE_FOR_NOVECTOR): New. (cp_convert_range_for, finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Add novector param. * init.cc (build_vec_init): Default novector to false. * method.cc (build_comparison_op): Likewise. * parser.cc (cp_parser_statement): Likewise. (cp_parser_for, cp_parser_c_for, cp_parser_range_for, cp_convert_range_for, cp_parser_iteration_statement, cp_parser_omp_for_loop, cp_parser_pragma): Support novector. (cp_parser_pragma_novector): New. * pt.cc (tsubst_expr): Likewise. * semantics.cc (finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Likewise. gcc/ChangeLog: * doc/extend.texi: Document it. gcc/testsuite/ChangeLog: * g++.dg/vect/vect.exp (support vect- prefix). * g++.dg/vect/vect-novector-pragma.cc: New test.
2023-07-28c++: devirtualization of array destruction [PR110057]Ng YongXiang1-4/+7
PR c++/110057 PR ipa/83054 gcc/cp/ChangeLog: * init.cc (build_vec_delete_1): Devirtualize array destruction. gcc/testsuite/ChangeLog: * g++.dg/warn/pr83054.C: Remove devirtualization warning. * g++.dg/lto/pr89335_0.C: Likewise. * g++.dg/tree-ssa/devirt-array-destructor-1.C: New test. * g++.dg/tree-ssa/devirt-array-destructor-2.C: New test. * g++.dg/warn/pr83054-2.C: New test. Signed-off-by: Ng Yong Xiang <yongxiangng@gmail.com>
2023-06-29c++: NSDMI instantiation during overload resolution [PR110468]Patrick Palka1-0/+4
Here we find ourselves instantiating the NSDMI for A<1>::m when computing argument conversions during overload resolution, and thus tf_conv is set. The flag causes mark_used for the constructor used in the NSDMI to exit early and not instantiate its noexcept-spec, which eventually leads to an ICE from nothrow_spec_p. This patch fixes this by clearing any special tsubst flags during instantiation of an NSDMI, since the result should be independent of the context that requires the instantiation. PR c++/110468 gcc/cp/ChangeLog: * init.cc (maybe_instantiate_nsdmi_init): Mask out all tsubst flags except for tf_warning_or_error. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept79.C: New test.
2023-06-12c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-2/+11
I previously applied this change in r13-4565 but reverted it due to PR108071. That PR was then fixed by r13-4712, but I didn't re-apply this change then because we weren't making the array static; since r14-1500 for PR110070 we now make the initializer array static, so let's bring this back. In situations where the maybe_init_list_as_range optimization isn't viable, we can build an initializer_list<string> with a loop over a constant array of string literals. This is represented using a VEC_INIT_EXPR, which required adjusting a couple of places that expected the initializer array to have the same type as the target array and fixing build_vec_init not to undo our efforts. PR c++/105838 gcc/cp/ChangeLog: * call.cc (convert_like_internal) [ck_list]: Use maybe_init_list_as_array. * constexpr.cc (cxx_eval_vec_init_1): Init might have a different type. * tree.cc (build_vec_init_elt): Likewise. * init.cc (build_vec_init): Handle from_array from a TARGET_EXPR. Retain TARGET_EXPR of a different type. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt5.C: New test.
2023-05-17c++: Don't try to initialize zero width bitfields in zero initialization ↵Jakub Jelinek1-6/+13
[PR109868] My GCC 12 change to avoid removing zero-sized bitfields as they are important for ABI and are needed for layout compatibility traits apparently causes zero sized bitfields to be initialized in the IL, which at least in 13+ results in ICEs in the ranger which is upset about zero precision types. I think we could even avoid initializing other unnamed bitfields, but unfortunately !CONSTRUCTOR_NO_CLEARING doesn't mean in the middle-end clearing of padding bits and until we have some new flag that represents the request to clear padding bits, I think it is better to keep zeroing non-zero sized unnamed bitfields. In addition to skipping those fields, I have changed the logic how UNION_TYPEs are handled, the current code was a little bit weird in that e.g. if first non-static data member had error_mark_node type, we'd happily zero initialize the second non-static data member, etc. 2023-05-17 Jakub Jelinek <jakub@redhat.com> PR c++/109868 * init.cc (build_zero_init_1): Don't initialize zero-width bitfields. For unions only initialize the first FIELD_DECL. * g++.dg/init/pr109868.C: New test.
2023-05-01c++: array DMI and member fn [PR109666]Jason Merrill1-23/+2
Here it turns out I also needed to adjust cfun when stepping out of the member function to instantiate the DMI. But instead of adding that tweak, let's unify with instantiate_body and just push_to_top_level instead of trying to do the minimum subset of it. There was no measurable change in compile time on stdc++.h. This should also resolve 109506 without yet another tweak. PR c++/109666 gcc/cp/ChangeLog: * name-lookup.cc (maybe_push_to_top_level) (maybe_pop_from_top_level): Split out... * pt.cc (instantiate_body): ...from here. * init.cc (maybe_instantiate_nsdmi_init): Use them. * name-lookup.h: Declare them.. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-array2.C: New test.
2023-04-26c++: remove nsdmi_inst hashtableJason Merrill1-6/+4
It occurred to me that we have a perfectly good DECL_INITIAL field to put the instantiated DMI into, we don't need a separate hash table. gcc/cp/ChangeLog: * init.cc (nsdmi_inst): Remove. (maybe_instantiate_nsdmi_init): Use DECL_INITIAL instead.
2023-03-30c++: anonymous union member reference [PR105452]Jason Merrill1-1/+1
While parsing the anonymous union, we don't yet know that it's an anonymous union, so we build the reference to 'v' in the static_assert relative to the union type. But at instantiation time we know it's an anonymous union, so we need to avoid trying to check access for 'v' in the union again; the simplest approach seemed to be to make accessible_p step out to the containing class. While looking at this I also noticed that we were having trouble with DMI in an anonymous union referring to members of the containing class; there we just need to give current_class_ptr the right type. PR c++/105452 gcc/cp/ChangeLog: * search.cc (type_context_for_name_lookup): New. (accessible_p): Handle anonymous union. * init.cc (maybe_instantiate_nsdmi_init): Use type_context_for_name_lookup. * parser.cc (cp_parser_class_specifier): Likewise. * cp-tree.h (type_context_for_name_lookup): Declare. gcc/testsuite/ChangeLog: * g++.dg/lookup/anon8.C: New test.
2023-03-21c++: DMI in template with virtual base [PR106890]Jason Merrill1-0/+14
When parsing a default member init we just build a CONVERT_EXPR for converting to a virtual base, and then expand that into the more complex form when we actually use the DMI in a constructor. But that wasn't working for the template case where we are considering the conversion at the point that the constructor needs the DMI instantiation, so it seemed like we were in a constructor already. And then when the other constructor tries to reuse the instantiation, it sees uses of the first constructor's parameters, and dies. So ensure that we get the CONVERT_EXPR in this case, too. PR c++/106890 gcc/cp/ChangeLog: * init.cc (maybe_instantiate_nsdmi_init): Don't leave current_function_decl set to a constructor. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template25.C: New test.
2023-03-16c++: __func__ and local class DMI [PR105809]Jason Merrill1-9/+18
As in 108242, we need to instantiate in the context of the enclosing function, not after it's gone. PR c++/105809 gcc/cp/ChangeLog: * init.cc (get_nsdmi): Split out... (maybe_instantiate_nsdmi_init): ...this function. * cp-tree.h: Declare it. * pt.cc (tsubst_expr): Use it. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-__func__3.C: New test.
2023-03-09c++: allocator temps in list of arrays [PR108773]Jason Merrill1-21/+57
The optimization to reuse the same allocator temporary for all string constructor calls was breaking on this testcase, because the temps were already in the argument to build_vec_init, and replacing them with references to one slot got confused with calls at multiple levels (for the initializer_list backing array, and then again for the array member of the std::array). Fixed by reusing the whole TARGET_EXPR instead of pulling out the slot; gimplification ensures that it's only initialized once. I also moved the check for initializing a std:: class down into the tree walk, and handle multiple temps within a single array element initialization. PR c++/108773 gcc/cp/ChangeLog: * init.cc (find_allocator_temps_r): New. (combine_allocator_temps): Replace find_allocator_temp. (build_vec_init): Adjust. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array18.C: New test. * g++.dg/cpp0x/initlist-array19.C: New test.
2023-01-23c++: Quash bogus -Wunused-value with new [PR107797]Marek Polacek1-0/+2
We shouldn't emit "right operand of comma operator has no effect" when that comma operator was created by the compiler for "new int{}". convert_to_void/COMPOUND_EXPR already checks warning_suppressed_p so we can just suppress -Wunused-value. PR c++/107797 gcc/cp/ChangeLog: * cvt.cc (ocp_convert): copy_warning when creating a new COMPOUND_EXPR. * init.cc (build_new_1): Suppress -Wunused-value on compiler-generated COMPOUND_EXPRs. gcc/testsuite/ChangeLog: * g++.dg/warn/Wunused-value-1.C: New test.
2023-01-16Update copyright years.Jakub Jelinek1-1/+1
2022-12-23c++: get_nsdmi in template context [PR108116]Patrick Palka1-0/+4
Here during ahead of time checking of C{}, we indirectly call get_nsdmi for C::m from finish_compound_literal, which in turn calls break_out_target_exprs for C::m's (non-templated) initializer, during which we build a call to A::~A and check expr_noexcept_p for it (from build_vec_delete_1). But this is all done with processing_template_decl set, so the built A::~A call is templated (whose form was recently changed by r12-6897-gdec8d0e5fa00ceb2) which expr_noexcept_p doesn't expect, and we crash. This patch fixes this by clearing processing_template_decl before the call to break_out_target_exprs from get_nsdmi. And since it more generally seems we shouldn't be seeing (or producing) non-templated trees in break_out_target_exprs, this patch also adds an assert to that effect. PR c++/108116 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_value): Clear processing_template_decl before calling break_out_target_exprs. * init.cc (get_nsdmi): Likewise. * tree.cc (break_out_target_exprs): Assert processing_template_decl is cleared. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/nsdmi-template24.C: New test.
2022-12-15c++: rename parameterJason Merrill1-4/+5
gcc/cp/ChangeLog: * init.cc (build_vec_init): Rename "flags" to "cleanup_flags" to distinguish from LOOKUP_*.
2022-12-12Revert "c++: build initializer_list<string> in a loop [PR105838]"Jason Merrill1-11/+2
This patch broke a couple of different patterns; reverting while I work on a fix. PR c++/108701 This reverts commit bd0485f20f4794f9787237706a6308473a8e9415.
2022-12-08c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-2/+11
The previous patch avoided building an initializer_list<string> at all when building a vector<string>, but in situations where that isn't possible, we could still build the initializer_list with a loop over a constant array. This is represented using a VEC_INIT_EXPR, which required adjusting a couple of places that expected the initializer array to have the same type as the target array and fixing build_vec_init not to undo our efforts. PR c++/105838 gcc/cp/ChangeLog: * call.cc (convert_like_internal) [ck_list]: Use maybe_init_list_as_array. * constexpr.cc (cxx_eval_vec_init_1): Init might have a different type. * tree.cc (build_vec_init_elt): Likewise. * init.cc (build_vec_init): Handle from_array from a TARGET_EXPR. Retain TARGET_EXPR of a different type. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt2.C: New test.
2022-12-08c++: fewer allocator temps [PR105838]Jason Merrill1-1/+58
In this PR, initializing the array of std::string to pass to the vector initializer_list constructor gets very confusing to the optimizers as the number of elements increases, primarily because of all the std::allocator temporaries passed to all the string constructors. Instead of creating one for each string, let's share an allocator between all the strings; we can do this safely because we know that std::allocator is stateless and that string doesn't care about the object identity of its allocator parameter. PR c++/105838 gcc/cp/ChangeLog: * cp-tree.h (is_std_allocator): Declare. * constexpr.cc (is_std_allocator): Split out from... (is_std_allocator_allocate): ...here. * init.cc (find_temps_r): New. (find_allocator_temp): New. (build_vec_init): Use it. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/allocator-opt1.C: New test.
2022-11-15c++: remove i_c_e_p parm from tsubst_copy_and_buildPatrick Palka1-4/+2
It seems the only and original purpose of tsubst_copy_and_build's integral_constant_expression_p boolean parameter (added in r116276, which predates the constexpr machinery) is to diagnose certain constructs that aren't allowed to appear in a C++98 integral constant expression context, specifically casts to a non-integral type (diagnosed from the *_CAST_EXPR case of tsubst_copy_and_build) or dependent names that resolve to a non-constant decl (diagnosed from the IDENTIFIER_NODE case of tsubst_copy_and_build). The parameter has no effect outside of C++98 AFAICT. But diagnosing such constructs should arguably be the job of the constexpr machinery (e.g. is_constant_expression) after substitution, and doing it during substitution by way of an additional parameter complicates the API of this workhorse function for what amounts to a couple of archaic C++98 restrictions. And it seems is_constant_expression already does a good job of diagnosing the aforementioned two constructs in C++98 mode, at least as far as our testsuite is concerned. So this patch removes this parameter from tsubst_copy_and_build, tsubst_expr and tsubst_copy_and_build_call_args. The only interesting changes are to potential_constant_expression_1 and the IDENTIFIER_NODE and *_CAST_EXPR cases of tsubst_copy_and_build; the rest are mechanical adjustments to the functions' signatures and their call sites. gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case *_CAST_EXPR>: Use cast_valid_in_integral_constant_expression_p instead of open coding it. * constraint.cc (tsubst_valid_expression_requirement): Adjust calls to tsubst_copy_and_build and tsubst_expr. (tsubst_constraint): Likewise. (satisfy_atom): Likewise. (diagnose_trait_expr): Likewise. * cp-tree.h (tsubst_copy_and_build): Remove i_c_e_p parameter. (tsubst_expr): Likewise. * init.cc (get_nsdmi): Adjust calls to tsubst_copy_and_build and tsubst_expr. * pt.cc (expand_integer_pack): Likewise. (instantiate_non_dependent_expr_internal): Likewise. (tsubst_friend_function): Likewise. (tsubst_attribute): Likewise. (instantiate_class_template): Likewise. (tsubst_template_arg): Likewise. (gen_elem_of_pack_expansion_instantiation): Likewise. (tsubst_fold_expr_init): Likewise. (tsubst_pack_expansion): Likewise. (tsubst_default_argument): Likewise. (tsubst_function_decl): Likewise. (tsubst_decl): Likewise. (tsubst_arg_types): Likewise. (tsubst_exception_specification): Likewise. (tsubst): Likewise. (tsubst_init): Likewise. (tsubst_copy): Likewise. (tsubst_omp_clause_decl): Likewise. (tsubst_omp_clauses): Likewise. (tsubst_copy_asm_operands): Likewise. (tsubst_omp_for_iterator): Likewise. (tsubst_expr): Likewise. Remove i_c_e_p parameter. (tsubst_omp_udr): Likewise. (tsubst_non_call_postfix_expression): Likewise. Remove i_c_e_p parameter. (tsubst_lambda_expr): Likewise. (tsubst_copy_and_build_call_args): Likewise. (tsubst_copy_and_build): Likewise. Remove i_c_e_p parameter. <case IDENTIFIER_NODE>: Adjust call to finish_id_expression following removal of i_c_e_p. <case *_CAST_EXPR>: Remove C++98-specific cast validity check guarded by i_c_e_p. (maybe_instantiate_noexcept): Adjust calls to tsubst_copy_and_build and tsubst_expr. (instantiate_body): Likewise. (instantiate_decl): Likewise. (tsubst_initializer_list): Likewise. (tsubst_enum): Likewise. gcc/objcp/ChangeLog: * objcp-lang.cc (objcp_tsubst_copy_and_build): Adjust calls to tsubst_copy_and_build and tsubst_expr. gcc/testsuite/ChangeLog: * g++.dg/template/crash55.C: Don't expect additional C++98-specific diagnostics. * g++.dg/template/ref3.C: Remove C++98-specific xfail.
2022-11-15c++: remove function_p parm from tsubst_copy_and_buildPatrick Palka1-1/+1
The function_p parameter of tsubst_copy_and_build (added in r69316) is inspected only in its IDENTIFIER_NODE case, where it controls whether we diagnose unqualified name lookup failure for the given identifier. But I think ever since r173965, we never substitute an IDENTIFIER_NODE with function_p=true for which the lookup can possibly fail, and therefore the flag is effectively unneeded. Before that commit, we would incorrectly repeat unqualified lookup for an ADL-enabled CALL_EXPR at instantiation time, which naturally could fail and thus motivated the flag. Afterwards, we no longer substitute an IDENTIFIER_NODE callee when koenig_p is true, so the flag isn't needed for its original purpose. What about when koenig_p=false? Apparently we still may have an IDENTIFIER_NODE callee in this case, namely when unqualified name lookup found a dependent local function declaration, but repeating that lookup can't fail (ditto for USING_DECL callees). So this patch removes this effectively unneeded parameter from tsubst_copy_and_build. It also updates an outdated comment in the CALL_EXPR case about when we may see an IDENTIFIER_NODE callee with koenig_p=false. gcc/cp/ChangeLog: * cp-lang.cc (objcp_tsubst_copy_and_build): Remove function_p parameter. * cp-objcp-common.h (objcp_tsubst_copy_and_build): Likewise. * cp-tree.h (tsubst_copy_and_build): Likewise. * init.cc (get_nsdmi): Adjust calls to tsubst_copy_and_build. * pt.cc (expand_integer_pack): Likewise. (instantiate_non_dependent_expr_internal): Likewise. (tsubst_function_decl): Likewise. (tsubst_arg_types): Likewise. (tsubst_exception_specification): Likewise. (tsubst): Likewise. (tsubst_copy_asm_operands): Likewise. (tsubst_expr): Likewise. (tsubst_non_call_postfix_expression): Likewise. (tsubst_lambda_expr): Likewise. (tsubst_copy_and_build_call_args): Likewise. (tsubst_copy_and_build): Remove function_p parameter and adjust function comment. Adjust recursive calls. <case CALL_EXPR>: Update outdated comment about when we can see an IDENTIFIER_NODE callee with koenig_p=false. (maybe_instantiate_noexcept): Adjust calls to tsubst_copy_and_build. gcc/objcp/ChangeLog: * objcp-lang.cc (objcp_tsubst_copy_and_build): Remove function_p parameter.
2022-10-07c++: track whether we expect a TARGET_EXPR to be elidedJason Merrill1-15/+16
A discussion at Cauldron made me think that with the formalization of copy elision in C++17, we should be able to determine before optimization which TARGET_EXPRs will become temporaries and which are initializers. This patch implements that: we set TARGET_EXPR_ELIDING_P if it's used as an initializer, and later check that we were right. There's an exception in the cp_gimplify_expr check to allow extra temporaries of non-addressable type: this is used by gimplify_init_ctor_preeval to materialize subobjects of a CONSTRUCTOR on the rhs of a MODIFY_EXPR rather than materializing the whole object. If the type isn't addressable, there's no way for a program to tell the difference, so this is a valid optimization. I considered changing replace_placeholders_for_class_temp_r to check TARGET_EXPR_ELIDING_P instead of potential_prvalue_result_of, but decided that would be wrong: if we have an eliding TARGET_EXPR inside a non-eliding one, we would miss replacing its placeholders. gcc/cp/ChangeLog: * cp-tree.h (TARGET_EXPR_ELIDING_P): New. (unsafe_copy_elision_p, set_target_expr_eliding) (cp_build_init_expr): Declare. * call.cc (unsafe_copy_elision_p): No longer static. (build_over_call, build_special_member_call) (build_new_method_call): Use cp_build_init_expr. * coroutines.cc (expand_one_await_expression) (build_actor_fn, flatten_await_stmt, handle_nested_conditionals) (await_statement_walker, morph_fn_to_coro): Use cp_build_init_expr. * cp-gimplify.cc (cp_gimplify_init_expr) (cp_gimplify_expr): Check TARGET_EXPR_ELIDING_P. (cp_fold_r): Propagate it. (cp_fold): Use cp_build_init_expr. * decl.cc (check_initializer): Use cp_build_init_expr. * except.cc (build_throw): Use cp_build_init_expr. * init.cc (get_nsdmi): Call set_target_expr_eliding. (perform_member_init, expand_default_init, expand_aggr_init_1) (build_new_1, build_vec_init): Use cp_build_init_expr. * method.cc (do_build_copy_constructor): Use cp_build_init_expr. * semantics.cc (simplify_aggr_init_expr, finalize_nrv_r) (finish_omp_reduction_clause): Use cp_build_init_expr. * tree.cc (build_target_expr): Call set_target_expr_eliding. (bot_manip): Copy TARGET_EXPR_ELIDING_P. * typeck.cc (cp_build_modify_expr): Call set_target_expr_eliding. (check_return_expr): Use cp_build_modify_expr. * typeck2.cc (split_nonconstant_init_1) (split_nonconstant_init): Use cp_build_init_expr. (massage_init_elt): Call set_target_expr_eliding. (process_init_constructor_record): Clear TARGET_EXPR_ELIDING_P on unsafe copy elision. (set_target_expr_eliding, cp_build_init_expr): New.
2022-10-07c++: catch parm initialization tweakJason Merrill1-11/+12
We want to push the INIT_EXPR inside the CLEANUP_POINT_EXPR for the same reason we want to push it into the MUST_NOT_THROW_EXPR: any cleanups follow the initialization. gcc/cp/ChangeLog: * init.cc (expand_default_init): Also push the INIT_EXPR inside a CLEANUP_POINT_EXPR.
2022-09-30c++: loop through array CONSTRUCTORJason Merrill1-1/+5
I noticed that we were ignoring all the special rules for when to use a simple INIT_EXPR for array initialization from a CONSTRUCTOR, because split_nonconstant_init_1 was also passing 1 to the from_array parameter. Arguably that's the real bug, but I think we can be flexible. The test that I noticed this with no longer fails without it. gcc/cp/ChangeLog: * init.cc (build_vec_init): Clear from_array for CONSTRUCTOR initializer.
2022-09-12c++: remove '_sfinae' suffix from functionsPatrick Palka1-1/+1
The functions abstract_virtuals_error cxx_constant_value get_target_expr instantiate_non_dependent_expr require_complete_type are each just a non-SFINAE-enabled wrapper for the corresponding SFINAE-enabled version that's suffixed by '_sfinae'. But this suffix is at best redundant since a 'complain' parameter already broadly conveys that a function is SFINAE-enabled, and having two such versions of a function is less concise than just using a default argument for 'complain' (and arguably no less mistake prone). So this patch squashes the two versions of each of the above functions by adding a default 'complain' argument to the SFINAE-enabled version whose '_sfinae' suffix we then remove. gcc/cp/ChangeLog: * call.cc (build_conditional_expr): Adjust calls to '_sfinae'-suffixed functions. (build_temp): Likewise. (convert_like_internal): Likewise. (convert_arg_to_ellipsis): Likewise. (build_over_call): Likewise. (build_cxx_call): Likewise. (build_new_method_call): Likewise. * constexpr.cc (cxx_eval_outermost_constant_expr): Likewise. (cxx_constant_value_sfinae): Rename to ... (cxx_constant_value): ... this. Document its default arguments. (fold_non_dependent_expr): Adjust function comment. * cp-tree.h (instantiate_non_dependent_expr_sfinae): Rename to ... (instantiate_non_dependent_expr): ... this. Give its 'complain' parameter a default argument. (get_target_expr_sfinae, get_target_expr): Likewise. (require_complete_type_sfinae, require_complete_type): Likewise. (abstract_virtuals_error_sfinae, abstract_virtuals_error): Likewise. (cxx_constant_value_sfinae, cxx_constant_value): Likewise. * cvt.cc (build_up_reference): Adjust calls to '_sfinae'-suffixed functions. (ocp_convert): Likewise. * decl.cc (build_explicit_specifier): Likewise. * except.cc (build_noexcept_spec): Likewise. * init.cc (build_new_1): Likewise. * pt.cc (expand_integer_pack): Likewise. (instantiate_non_dependent_expr_internal): Adjust function comment. (instantiate_non_dependent_expr): Rename to ... (instantiate_non_dependent_expr_sfinae): ... this. Document its default argument. (tsubst_init): Adjust calls to '_sfinae'-suffixed functions. (fold_targs_r): Likewise. * semantics.cc (finish_compound_literal): Likewise. (finish_decltype_type): Likewise. (cp_build_bit_cast): Likewise. * tree.cc (build_cplus_new): Likewise. (get_target_expr): Rename to ... (get_target_expr_sfinae): ... this. Document its default argument. * typeck.cc (require_complete_type): Rename to ... (require_complete_type_sfinae): ... this. Document its default argument. (cp_build_array_ref): Adjust calls to '_sfinae'-suffixed functions. (convert_arguments): Likewise. (cp_build_binary_op): Likewise. (build_static_cast_1): Likewise. (cp_build_modify_expr): Likewise. (convert_for_initialization): Likewise. * typeck2.cc (abstract_virtuals_error): Rename to ... (abstract_virtuals_error_sfinae): ... this. Document its default argument. (build_functional_cast_1): Adjust calls to '_sfinae'-suffixed functions.
2022-07-22remove 'continue' as last statement in loopMartin Liska1-1/+0
PR other/106370 gcc/cp/ChangeLog: * init.cc (sort_mem_initializers): Remove continue as last stmt in a loop. libiberty/ChangeLog: * _doprnt.c: Remove continue as last stmt in a loop.
2022-05-15c++: array {}-init [PR105589]Jason Merrill1-4/+3
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.
2022-05-09c++: constexpr init of union sub-aggr w/ base [PR105491]Patrick Palka1-3/+3
Here ever since r10-7313-gb599bf9d6d1e18, reduced_constant_expression_p in C++11/14 is rejecting the marked sub-aggregate initializer (of type S) W w = {.D.2445={.s={.D.2387={.m=0}, .b=0}}}; ^ ultimately because said initializer has CONSTRUCTOR_NO_CLEARING set, hence the function must verify that all fields of S are initialized. And before C++17 it doesn't expect to see base class fields (since next_initializable_field skips over them), so the presence thereof causes r_c_e_p to return false. The reason r10-7313-gb599bf9d6d1e18 causes this is because in that commit we began using CONSTRUCTOR_NO_CLEARING to precisely track whether we're in middle of activating a union member. This ends up affecting clear_no_implicit_zero, which recurses into sub-aggregate initializers only if the outer initializer has CONSTRUCTOR_NO_CLEARING set. After that commit, the outer union initializer above no longer has the flag set at this point and so clear_no_implicit_zero no longer recurses into the marked inner initializer. But arguably r_c_e_p should be able to accept the marked initializer regardless of whether CONSTRUCTOR_NO_CLEARING is set. The primary bug therefore seems to be that r_c_e_p relies on next_initializable_field which skips over base class fields in C++11/14. To fix this, this patch introduces a new helper function next_subobject_field which is like next_initializable_field except that it never skips base class fields, and makes r_c_e_p use it. This patch then renames next_initializable_field to next_aggregate_field (and makes it skip over vptr fields again). PR c++/105491 gcc/cp/ChangeLog: * call.cc (field_in_pset): Adjust after next_initializable_field renaming. (build_aggr_conv): Likewise. (convert_like_internal): Likewise. (type_has_extended_temps): Likewise. * class.cc (default_init_uninitialized_part): Likewise. (finish_struct): Likewise. * constexpr.cc (cx_check_missing_mem_inits): Likewise. (reduced_constant_expression_p): Use next_subobject_field instead. * cp-gimplify.cc (get_source_location_impl_type): Adjust after next_initializable_field renaming. (fold_builtin_source_location): Likewise. * cp-tree.h (next_initializable_field): Rename to ... (next_aggregate_field): ... this. (next_subobject_field): Declare. * decl.cc (next_aggregate_field): Renamed from ... (next_initializable_field): ... this. Skip over vptr fields again. (next_subobject_field): Define. (reshape_init_class): Adjust after next_initializable_field renaming. * init.cc (build_value_init_noctor): Likewise. (emit_mem_initializers): Likewise. * lambda.cc (build_capture_proxy): Likewise. * method.cc (build_comparison_op): Likewise. * pt.cc (maybe_aggr_guide): Likewise. * tree.cc (structural_type_p): Likewise. * typeck2.cc (split_nonconstant_init_1): Likewise. (digest_init_r): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-union7.C: New test. * g++.dg/cpp0x/constexpr-union7a.C: New test. * g++.dg/cpp2a/constinit17.C: New test.
2022-04-13c++: NRV and ref-extended temps [PR101442]Jason Merrill1-1/+1
This issue goes back to r83221, where the cleanup for extended ref temps changed from being unconditional to being tied to the declaration they formed part of the initializer for. The named return value optimization changes the cleanup for the NRV variable to only run on the EH path; we don't want that change to affect temporary cleanups. The perform_member_init change isn't necessary (there 'decl' is a COMPONENT_REF), it's just for consistency. PR c++/101442 gcc/cp/ChangeLog: * decl.cc (cp_finish_decl): Don't pass decl to push_cleanup. * init.cc (perform_member_init): Likewise. * semantics.cc (push_cleanup): Adjust comment. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-nrv1.C: New test.
2022-04-12c++: non-array new alignment [PR102071]Jason Merrill1-1/+1
While considering the PR102071 patch for backporting, I noticed that I was considering the alignment of the array new cookie even when there isn't one because we aren't allocating an array. PR c++/102071 gcc/cp/ChangeLog: * init.cc (build_new_1): Check array_p for alignment. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/aligned-new9.C: Add single-object test.
2022-04-11c++: -Wplacement-new and anon union member [PR100370]Jason Merrill1-0/+5
This bug was an object/value confusion; we are interested in the size of *b.ip, but instead the code was calculating the size of b.ip itself. This seems to be because compute_objsize will compute the size of whatever object it can find in the argument: if you pass it a VAR_DECL, it gives you the size of that variable. If you pass it an ADDR_EXPR of a VAR_DECL, it again gives you the size of the variable. The way you can tell the difference is by looking at the deref member of access_ref: if it's -1, the argument is a pointer to the object. Since that's what we're interested in, we should check for that, like check_dangling_stores does. This regressed some tests because compute_objsize_r was wrongly zeroing deref in the POINTER_PLUS_EXPR handling; adding an offset to a pointer doesn't change whether the pointer is itself a variable or a pointer to one. In fact, handling POINTER_PLUS_EXPR only really makes sense for deref == -1, where we're adjusting a pointer to the variable. PR c++/100370 gcc/cp/ChangeLog: * init.cc (warn_placement_new_too_small): Check deref. gcc/ChangeLog: * pointer-query.cc (compute_objsize_r) [POINTER_PLUS_EXPR]: Require deref == -1. gcc/testsuite/ChangeLog: * g++.dg/warn/Wplacement-new-size-11.C: New test.
2022-04-06c++: -Wunused-value and array init [PR104702]Jason Merrill1-3/+2
Here, because of problems with the new warning-control code and expressions that change location, the suppress_warning on the INDIRECT_REF didn't work. Those problems still need to be worked out, but it's simple to avoid needing to use suppress_warning in the first place by using a reference instead. PR c++/104702 gcc/cp/ChangeLog: * init.cc (build_vec_init): Use a reference for the result. gcc/testsuite/ChangeLog: * g++.dg/warn/Wunused-19.C: New test.