aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
AgeCommit message (Collapse)AuthorFilesLines
2024-02-12c++: ICE with reinterpret_cast and switch [PR113545]Marek Polacek1-0/+10
Jason, this is the patch you proposed for PR113545. It looks very safe so I'm posting it here so that it's not forgotten. PR c++/113545 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_switch_expr): If the condition doesn't reduce to an INTEGER_CST, consider it non-constant. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-reinterpret3.C: Remove dg-ice.
2024-02-01c++: no_unique_address and constexpr [PR112439]Jason Merrill1-0/+1
Here, because we don't build a CONSTRUCTOR for an empty base, we were wrongly marking the Foo CONSTRUCTOR as complete after initializing the Empty member. Fixed by checking empty_base here as well. PR c++/112439 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_store_expression): Check empty_base before marking a CONSTRUCTOR readonly. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/no_unique_address15.C: New test.
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-09OpenMP: lvalue parsing for map/to/from clauses (C++)Julian Brown1-0/+1
This patch supports "lvalue" parsing (or "locator list item type" parsing) for several OpenMP clause types for C++, as required for OpenMP 5.0 and above. This version has been rebased -- some things have changed around template handling recently, e.g. removal of build_non_dependent_expr and tsubst_copy. A new potential corner-case issue has shown up regarding implicit mapping of references to pointer to pointers -- an interaction with the post-review fixes/rework for the patch here: https://gcc.gnu.org/pipermail/gcc-patches/2023-November/638602.html Which fixed the (new) tests baseptrs-[6789].C. I've noted that for now in the patch, and adjusted the baseptrs-[46].C tests slightly to accommodate. 2024-01-08 Julian Brown <julian@codesourcery.com> gcc/c-family/ * c-common.h (c_omp_address_inspector): Remove static from get_origin and maybe_unconvert_ref methods. * c-omp.cc (c_omp_split_clauses): Support OMP_ARRAY_SECTION. (c_omp_address_inspector::map_supported_p): Handle OMP_ARRAY_SECTION. (c_omp_address_inspector::get_origin): Avoid dereferencing possibly NULL type when processing template decls. (c_omp_address_inspector::maybe_unconvert_ref): Likewise. gcc/cp/ * constexpr.cc (potential_consant_expression_1): Handle OMP_ARRAY_SECTION. * cp-tree.h (grok_omp_array_section, build_omp_array_section): Add prototypes. * decl2.cc (grok_omp_array_section): New function. * error.cc (dump_expr): Handle OMP_ARRAY_SECTION. * parser.cc (cp_parser_new): Initialize parser->omp_array_section_p. (cp_parser_statement_expr): Disallow array sections. (cp_parser_postfix_open_square_expression): Support OMP_ARRAY_SECTION parsing. (cp_parser_parenthesized_expression_list, cp_parser_lambda_expression, cp_parser_braced_list): Disallow array sections. (cp_parser_omp_var_list_no_open): Remove ALLOW_DEREF parameter, add MAP_LVALUE in its place. Support generalised lvalue parsing for OpenMP map, to and from clauses. Use OMP_ARRAY_SECTION code instead of TREE_LIST to represent OpenMP array sections. (cp_parser_omp_var_list): Remove ALLOW_DEREF parameter, add MAP_LVALUE. Pass to cp_parser_omp_var_list_no_open. (cp_parser_oacc_data_clause): Update call to cp_parser_omp_var_list. (cp_parser_omp_clause_map): Add sk_omp scope around cp_parser_omp_var_list_no_open call. * parser.h (cp_parser): Add omp_array_section_p field. * pt.cc (tsubst, tsubst_copy, tsubst_omp_clause_decl, tsubst_copy_and_build): Add OMP_ARRAY_SECTION support. * semantics.cc (handle_omp_array_sections_1, handle_omp_array_sections, cp_oacc_check_attachments, finish_omp_clauses): Use OMP_ARRAY_SECTION instead of TREE_LIST where appropriate. Handle more types of map expression. * typeck.cc (build_omp_array_section): New function. gcc/ * gimplify.cc (gimplify_expr): Ensure OMP_ARRAY_SECTION has been processed out before gimplification. * tree-pretty-print.cc (dump_generic_node): Support OMP_ARRAY_SECTION. * tree.def (OMP_ARRAY_SECTION): New tree code. gcc/testsuite/ * c-c++-common/gomp/map-6.c: Update expected output. * c-c++-common/gomp/target-enter-data-1.c: Update scan test. * g++.dg/gomp/array-section-1.C: New test. * g++.dg/gomp/array-section-2.C: New test. * g++.dg/gomp/bad-array-section-1.C: New test. * g++.dg/gomp/bad-array-section-2.C: New test. * g++.dg/gomp/bad-array-section-3.C: New test. * g++.dg/gomp/bad-array-section-4.C: New test. * g++.dg/gomp/bad-array-section-5.C: New test. * g++.dg/gomp/bad-array-section-6.C: New test. * g++.dg/gomp/bad-array-section-7.C: New test. * g++.dg/gomp/bad-array-section-8.C: New test. * g++.dg/gomp/bad-array-section-9.C: New test. * g++.dg/gomp/bad-array-section-10.C: New test. * g++.dg/gomp/bad-array-section-11.C: New test. * g++.dg/gomp/has_device_addr-non-lvalue-1.C: New test. * g++.dg/gomp/pr67522.C: Update expected output. * g++.dg/gomp/ind-base-3.C: New test. * g++.dg/gomp/map-assignment-1.C: New test. * g++.dg/gomp/map-inc-1.C: New test. * g++.dg/gomp/map-lvalue-ref-1.C: New test. * g++.dg/gomp/map-ptrmem-1.C: New test. * g++.dg/gomp/map-ptrmem-2.C: New test. * g++.dg/gomp/map-static-cast-lvalue-1.C: New test. * g++.dg/gomp/map-ternary-1.C: New test. * g++.dg/gomp/member-array-2.C: New test. libgomp/ * testsuite/libgomp.c++/baseptrs-4.C: Remove commented-out cases that now work. * testsuite/libgomp.c++/baseptrs-6.C: New test. * testsuite/libgomp.c++/ind-base-1.C: New test. * testsuite/libgomp.c++/ind-base-2.C: New test. * testsuite/libgomp.c++/lvalue-tofrom-1.C: New test. * testsuite/libgomp.c++/lvalue-tofrom-2.C: New test. * testsuite/libgomp.c++/map-comma-1.C: New test. * testsuite/libgomp.c++/map-rvalue-ref-1.C: New test. * testsuite/libgomp.c++/struct-ref-1.C: New test. * testsuite/libgomp.c-c++-common/array-field-1.c: New test. * testsuite/libgomp.c-c++-common/array-of-struct-1.c: New test. * testsuite/libgomp.c-c++-common/array-of-struct-2.c: New test.
2024-01-03Update copyright years.Jakub Jelinek1-1/+1
2023-12-20c++: Check null pointer deref when calling memfn in constexpr [PR102420]Nathaniel Shead1-0/+14
Calling a non-static member function on a null pointer is undefined behaviour (see [expr.ref] p8) and should error in constant evaluation, even if the 'this' pointer is never actually accessed within that function. One catch is that currently, the function pointer conversion operator for lambdas passes a null pointer as the 'this' pointer to the underlying 'operator()', so for now we ignore such calls. PR c++/102420 gcc/cp/ChangeLog: * constexpr.cc (cxx_bind_parameters_in_call): Check for calling non-static member functions with a null pointer. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-memfn2.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-12-16c++: Fix unchecked use of CLASSTYPE_AS_BASE [PR113031]Nathaniel Shead1-1/+2
My previous commit (naively) assumed that a TREE_CODE of RECORD_TYPE or UNION_TYPE was sufficient for optype to be considered a "class type". However, this does not account for e.g. template type parameters of record or union type. This patch corrects to check for CLASS_TYPE_P before checking for as-base conversion. PR c++/113031 gcc/cp/ChangeLog: * constexpr.cc (cxx_fold_indirect_ref_1): Check for CLASS_TYPE before using CLASSTYPE_AS_BASE. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/pr113031.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-12-13c++: End lifetime of objects in constexpr after destructor call [PR71093]Nathaniel Shead1-22/+126
This patch adds checks for using objects after they've been manually destroyed via explicit destructor call. Currently this is only implemented for 'top-level' objects; FIELD_DECLs and individual elements of arrays will need a lot more work to track correctly and are left for a future patch. The other limitation is that destruction of parameter objects is checked too 'early', happening at the end of the function call rather than the end of the owning full-expression as they should be for consistency; see cpp2a/constexpr-lifetime2.C. This is because I wasn't able to find a good way to link the constructed parameter declarations with the variable declarations that are actually destroyed later on to propagate their lifetime status, so I'm leaving this for a later patch. PR c++/71093 gcc/cp/ChangeLog: * constexpr.cc (constexpr_global_ctx::get_value_ptr): Don't return NULL_TREE for objects we're initializing. (constexpr_global_ctx::destroy_value): Rename from remove_value. Only mark real variables as outside lifetime. (constexpr_global_ctx::clear_value): New function. (destroy_value_checked): New function. (cxx_eval_call_expression): Defer complaining about non-constant arg0 for operator delete. Use remove_value_safe. (cxx_fold_indirect_ref_1): Handle conversion to 'as base' type. (outside_lifetime_error): Include name of object we're accessing. (cxx_eval_store_expression): Handle clobbers. Improve error messages. (cxx_eval_constant_expression): Use remove_value_safe. Clear bind variables before entering body. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-lifetime1.C: Improve error message. * g++.dg/cpp1y/constexpr-lifetime2.C: Likewise. * g++.dg/cpp1y/constexpr-lifetime3.C: Likewise. * g++.dg/cpp1y/constexpr-lifetime4.C: Likewise. * g++.dg/cpp2a/bitfield2.C: Likewise. * g++.dg/cpp2a/constexpr-new3.C: Likewise. New check. * g++.dg/cpp1y/constexpr-lifetime7.C: New test. * g++.dg/cpp2a/constexpr-lifetime1.C: New test. * g++.dg/cpp2a/constexpr-lifetime2.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-12-13c++: fix in-charge parm in constexprJason Merrill1-0/+13
I was puzzled by the proposed patch for PR71093 specifically ignoring the in-charge parameter; the problem turned out to be that when cxx_eval_call_expression jumps from the clone to the cloned function, it assumes that the latter has the same parameters, and so the in-charge parm doesn't get an argument. Since a class with vbases can't have constexpr 'tors there isn't actually a need for an in-charge parameter in a destructor, but we used to use it for deleting destructors and never removed it. I have a patch to do that for GCC 15, but for now let's work around it. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Handle missing in-charge argument.
2023-12-13c++: constant direct-initialization [PR108243]Jason Merrill1-1/+15
When testing the proposed patch for PR71093 I noticed that it changed the diagnostic for consteval-prop6.C. I then noticed that the diagnostic wasn't very helpful either way; it was complaining about modification of the 'x' variable, but it's not a problem to initialize a local variable with a consteval constructor as long as the value is actually constant, we want to know why the value isn't constant. And then it turned out that this also fixed a missed-optimization bug in the testsuite. PR c++/108243 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Turn a constructor CALL_EXPR into a TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval-prop6.C: Adjust diagnostic. * g++.dg/opt/is_constant_evaluated3.C: Remove xfails.
2023-12-04c++: implement P2564, consteval needs to propagate up [PR107687]Marek Polacek1-2/+2
This patch implements P2564, described at <wg21.link/p2564>, whereby certain functions are promoted to consteval. For example: consteval int id(int i) { return i; } template <typename T> constexpr int f(T t) { return t + id(t); // id causes f<int> to be promoted to consteval } void g(int i) { f (3); } now compiles. Previously the code was ill-formed: we would complain that 't' in 'f' is not a constant expression. Since 'f' is now consteval, it means that the call to id(t) is in an immediate context, so doesn't have to produce a constant -- this is how we allow consteval functions composition. But making 'f<int>' consteval also means that the call to 'f' in 'g' must yield a constant; failure to do so results in an error. I made the effort to have cc1plus explain to us what's going on. For example, calling f(i) produces this neat diagnostic: w.C:11:11: error: call to consteval function 'f<int>(i)' is not a constant expression 11 | f (i); | ~~^~~ w.C:11:11: error: 'i' is not a constant expression w.C:6:22: note: 'constexpr int f(T) [with T = int]' was promoted to an immediate function because its body contains an immediate-escalating expression 'id(t)' 6 | return t + id(t); // id causes f<int> to be promoted to consteval | ~~^~~ which hopefully makes it clear what's going on. Implementing this proposal has been tricky. One problem was delayed instantiation: instantiating a function can set off a domino effect where one call promotes a function to consteval but that then means that another function should also be promoted, etc. In v1, I addressed the delayed instantiation problem by instantiating trees early, so that we can escalate functions right away. That caused a number of problems, and in certain cases, like consteval-prop3.C, it can't work, because we need to wait till EOF to see the definition of the function anyway. Overeager instantiation tends to cause diagnostic problems too. In v2, I attempted to move the escalation to the gimplifier, at which point all templates have been instantiated. That attempt flopped, however, because once we've gimplified a function, its body is discarded and as a consequence, you can no longer evaluate a call to that function which is required for escalating, which needs to decide if a call is a constant expression or not. Therefore, we have to perform the escalation before gimplifying, but after instantiate_pending_templates. That's not easy because we have no way to walk all the trees. In the v2 patch, I use two vectors: one to store function decls that may become consteval, and another to remember references to immediate-escalating functions. Unfortunately the latter must also stash functions that call immediate-escalating functions. Consider: int g(int i) { f<int>(i); // f is immediate-escalating } where g itself is not immediate-escalating, but we have to make sure that if f gets promoted to consteval, we give an error. A new option, -fno-immediate-escalation, is provided to suppress escalating functions. v2 also adds a new flag, DECL_ESCALATION_CHECKED_P, so that we don't escalate a function multiple times, and so that we can distinguish between explicitly consteval functions and functions that have been promoted to consteval. In v3, I removed one of the new vectors and changed the other one to a hash set. This version also contains numerous cleanups. v4 merges find_escalating_expr_r into cp_fold_immediate_r. It also adds a new optimization in cp_fold_function. v5 greatly simplifies the code. v6 simplifies the code further and removes an ff_ flag. v7 removes maybe_promote_function_to_consteval and further simplifies cp_fold_immediate_r logic. v8 removes maybe_store_immediate_escalating_fn. PR c++/107687 PR c++/110997 gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Update __cpp_consteval. * c-opts.cc (c_common_post_options): Pre-C++20, unset flag_immediate_escalation. * c.opt (fimmediate-escalation): New option. gcc/cp/ChangeLog: * call.cc (in_immediate_context): No longer static. * constexpr.cc (cxx_eval_call_expression): Adjust assert. * cp-gimplify.cc (deferred_escalating_exprs): New vec. (remember_escalating_expr): New. (enum fold_flags): Remove ff_fold_immediate. (immediate_escalating_function_p): New. (unchecked_immediate_escalating_function_p): New. (promote_function_to_consteval): New. (cp_fold_immediate): Move above. Return non-null if any errors were emitted. (maybe_explain_promoted_consteval): New. (cp_gimplify_expr) <case CALL_EXPR>: Assert we've handled all immediate invocations. (taking_address_of_imm_fn_error): New. (cp_fold_immediate_r): Merge ADDR_EXPR and PTRMEM_CST cases. Implement P2564 - promoting functions to consteval. <case CALL_EXPR>: Implement P2564 - promoting functions to consteval. (cp_fold_r): If an expression turns into a CALL_EXPR after cp_fold, call cp_fold_immediate_r on the CALL_EXPR. (cp_fold_function): Set DECL_ESCALATION_CHECKED_P if deferred_escalating_exprs does not contain current_function_decl. (process_and_check_pending_immediate_escalating_fns): New. * cp-tree.h (struct lang_decl_fn): Add escalated_p bit-field. (DECL_ESCALATION_CHECKED_P): New. (immediate_invocation_p): Declare. (process_pending_immediate_escalating_fns): Likewise. * decl2.cc (c_parse_final_cleanups): Set at_eof to 2 after all templates have been instantiated; and to 3 at the end of the function. Call process_pending_immediate_escalating_fns. * error.cc (dump_template_bindings): Check at_eof against an updated value. * module.cc (trees_out::lang_decl_bools): Stream escalated_p. (trees_in::lang_decl_bools): Likewise. * pt.cc (push_tinst_level_loc): Set at_eof to 3, not 2. * typeck.cc (cp_build_addr_expr_1): Don't check DECL_IMMEDIATE_FUNCTION_P. gcc/ChangeLog: * doc/invoke.texi: Document -fno-immediate-escalation. libstdc++-v3/ChangeLog: * testsuite/18_support/comparisons/categories/zero_neg.cc: Add dg-prune-output. * testsuite/std/format/string_neg.cc: Add dg-error. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if10.C: Remove dg-error. * g++.dg/cpp23/consteval-if2.C: Likewise. * g++.dg/cpp23/feat-cxx2b.C: Adjust expected value of __cpp_consteval. * g++.dg/cpp26/feat-cxx26.C: Likewise. * g++.dg/cpp2a/consteval-memfn1.C: Add dg-error. * g++.dg/cpp2a/consteval11.C: Likewise. * g++.dg/cpp2a/consteval3.C: Adjust dg-error. * g++.dg/cpp2a/consteval34.C: Add dg-error. * g++.dg/cpp2a/consteval36.C: Likewise. * g++.dg/cpp2a/consteval9.C: Likewise. * g++.dg/cpp2a/feat-cxx2a.C: Adjust expected value of __cpp_consteval. * g++.dg/cpp2a/spaceship-synth9.C: Adjust dg-error. * g++.dg/cpp2a/consteval-prop1.C: New test. * g++.dg/cpp2a/consteval-prop10.C: New test. * g++.dg/cpp2a/consteval-prop11.C: New test. * g++.dg/cpp2a/consteval-prop12.C: New test. * g++.dg/cpp2a/consteval-prop13.C: New test. * g++.dg/cpp2a/consteval-prop14.C: New test. * g++.dg/cpp2a/consteval-prop15.C: New test. * g++.dg/cpp2a/consteval-prop16.C: New test. * g++.dg/cpp2a/consteval-prop17.C: New test. * g++.dg/cpp2a/consteval-prop18.C: New test. * g++.dg/cpp2a/consteval-prop19.C: New test. * g++.dg/cpp2a/consteval-prop20.C: New test. * g++.dg/cpp2a/consteval-prop2.C: New test. * g++.dg/cpp2a/consteval-prop3.C: New test. * g++.dg/cpp2a/consteval-prop4.C: New test. * g++.dg/cpp2a/consteval-prop5.C: New test. * g++.dg/cpp2a/consteval-prop6.C: New test. * g++.dg/cpp2a/consteval-prop7.C: New test. * g++.dg/cpp2a/consteval-prop8.C: New test. * g++.dg/cpp2a/consteval-prop9.C: New test.
2023-12-04c++: fix constexpr noreturn diagnosticJason Merrill1-1/+2
Mentioning a noreturn function does not involve an lvalue-rvalue conversion. gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1): Fix check for loading volatile lvalue. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-noreturn1.C: New test.
2023-11-29c++: P2280R4, Using unknown refs in constant expr [PR106650]Marek Polacek1-1/+7
This patch is an attempt to implement (part of?) P2280, Using unknown pointers and references in constant expressions. (Note that R4 seems to only allow References to unknown/Accesses via this, but not Pointers to unknown.) This patch works to the extent that the test case added in [expr.const] works as expected, as well as the test in <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2280r4.html#the-this-pointer> Most importantly, the proposal makes this compile: template <typename T, size_t N> constexpr auto array_size(T (&)[N]) -> size_t { return N; } void check(int const (&param)[3]) { constexpr auto s = array_size(param); static_assert (s == 3); } and I think it would be a pity not to have it in GCC 14. What still doesn't work is the test in $3.2: struct A2 { constexpr int f() { return 0; } }; struct B2 : virtual A2 {}; void f2(B2 &b) { constexpr int k = b.f(); } where we say error: '* & b' is not a constant expression This will be fixed in the future. PR c++/106650 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression) <case PARM_DECL>: Allow reference to unknown/this as per P2280. <case VAR_DECL>: Allow reference to unknown as per P2280. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-array-ptr6.C: Remove dg-error. * g++.dg/cpp0x/constexpr-ref12.C: Likewise. * g++.dg/cpp0x/constexpr-ref2.C: Adjust dg-error. * g++.dg/cpp0x/noexcept34.C: Remove dg-error. * g++.dg/cpp1y/lambda-generic-const10.C: Likewise. * g++.dg/cpp0x/constexpr-ref13.C: New test. * g++.dg/cpp1z/constexpr-ref1.C: New test. * g++.dg/cpp1z/constexpr-ref2.C: New test. * g++.dg/cpp2a/constexpr-ref1.C: New test.
2023-11-16c++: constantness of call to function pointer [PR111703]Patrick Palka1-1/+6
potential_constant_expression for CALL_EXPR tests FUNCTION_POINTER_TYPE_P on the callee rather than on the type of the callee, which means we always pass want_rval=any when recursing and so may fail to identify a non-constant function pointer callee as such. Fixing this turns out to further work around PR111703. PR c++/111703 PR c++/107939 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Fix FUNCTION_POINTER_TYPE_P test. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-fn8.C: Extend test. * g++.dg/diagnostic/constexpr4.C: New test.
2023-11-15c++: constantness of local var in constexpr fn [PR111703, PR112269]Patrick Palka1-2/+2
potential_constant_expression was incorrectly treating most local variables from a constexpr function as constant because it wasn't considering the 'now' parameter. This patch fixes this by relaxing its var_in_maybe_constexpr_fn checks accordingly, which turns out to partially fix two recently reported regressions: PR111703 is a regression caused by r11-550-gf65a3299a521a4 for restricting constexpr evaluation during warning-dependent folding. The mechanism is intended to restrict only constant evaluation of the instantiated non-dependent expression, but it also ends up restricting constant evaluation occurring during instantiation of the expression, in particular when instantiating the converted argument 'x' (a VIEW_CONVERT_EXPR) into a copy constructor call. This seems like a flaw in the mechanism, though I don't know if we want to fix the mechanism or get rid of it completely since the original testcases which motivated the mechanism are fixed more simply by r13-1225-gb00b95198e6720. In any case, this patch partially fixes this by making us correctly treat 'x' as non-constant which prevents the problematic warning-dependent folding from occurring at all. PR112269 is caused by r14-4796-g3e3d73ed5e85e7 for merging tsubst_copy into tsubst_copy_and_build. tsubst_copy used to exit early when 'args' was empty, behavior which that commit deliberately didn't preserve. This early exit masked the fact that COMPLEX_EXPR wasn't handled by tsubst at all, and is a tree code that apparently we could see during warning-dependent folding on some targets. A complete fix is to add handling for this tree code in tsubst_expr, but this patch should fix the reported testsuite failures since the COMPLEX_EXPRs that crop up in <complex> are considered non-constant expressions after this patch. PR c++/111703 PR c++/112269 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case VAR_DECL>: Only consider var_in_maybe_constexpr_fn if 'now' is false. <case INDIRECT_REF>: Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-fn8.C: New test.
2023-10-20c++: remove NON_DEPENDENT_EXPR, part 1Patrick Palka1-9/+0
This tree code dates all the way back to r69130[1] which implemented typing of non-dependent expressions. Its motivation was never clear (to me at least) since its documentation in e.g. cp-tree.def doesn't seem accurate anymore. build_non_dependent_expr has since gained a bunch of edge cases about whether or how to wrap certain templated trees, making it hard to reason about in general. So this patch removes this tree code, and temporarily turns build_non_dependent_expr into the identity function. The subsequent patch will remove build_non_dependent_expr and adjust its callers appropriately. We now need to more thoroughly handle templated (sub)trees in a couple of places which previously didn't need to since they didn't look through NON_DEPENDENT_EXPR. [1]: https://gcc.gnu.org/pipermail/gcc-patches/2003-July/109355.html gcc/c-family/ChangeLog: * c-warn.cc (check_address_or_pointer_of_packed_member): Handle type-dependent callee of CALL_EXPR. gcc/cp/ChangeLog: * class.cc (instantiate_type): Remove NON_DEPENDENT_EXPR handling. * constexpr.cc (cxx_eval_constant_expression): Likewise. (potential_constant_expression_1): Likewise. * coroutines.cc (coro_validate_builtin_call): Don't expect ALIGNOF_EXPR to be wrapped in NON_DEPENDENT_EXPR. * cp-objcp-common.cc (cp_common_init_ts): Remove NON_DEPENDENT_EXPR handling. * cp-tree.def (NON_DEPENDENT_EXPR): Remove. * cp-tree.h (build_non_dependent_expr): Temporarily redefine as the identity function. * cvt.cc (maybe_warn_nodiscard): Handle type-dependent and variable callee of CALL_EXPR. * cxx-pretty-print.cc (cxx_pretty_printer::expression): Remove NON_DEPENDENT_EXPR handling. * error.cc (dump_decl): Likewise. (dump_expr): Likewise. * expr.cc (mark_use): Likewise. (mark_exp_read): Likewise. * pt.cc (build_non_dependent_expr): Remove. * tree.cc (lvalue_kind): Remove NON_DEPENDENT_EXPR handling. (cp_stabilize_reference): Likewise. * typeck.cc (warn_for_null_address): Likewise. (cp_build_binary_op): Handle type-dependent SIZEOF_EXPR operands. (cp_build_unary_op) <case TRUTH_NOT_EXPR>: Don't fold inside a template. gcc/testsuite/ChangeLog: * g++.dg/concepts/var-concept3.C: Adjust expected diagnostic for attempting to call a variable concept. Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-19c++: indirect change of active union member in constexpr [PR101631,PR102286]Nathaniel Shead1-47/+119
This patch adds checks for attempting to change the active member of a union by methods other than a member access expression. To be able to properly distinguish `*(&u.a) = ` from `u.a = `, this patch redoes the solution for c++/59950 to avoid extranneous *&; it seems that the only case that needed the workaround was when copying empty classes. This patch also ensures that constructors for a union field mark that field as the active member before entering the call itself; this ensures that modifications of the field within the constructor's body don't cause false positives (as these will not appear to be member access expressions). This means that we no longer need to start the lifetime of empty union members after the constructor body completes. As a drive-by fix, this patch also ensures that value-initialised unions are considered to have activated their initial member for the purpose of checking stores and accesses, which catches some additional mistakes pre-C++20. PR c++/101631 PR c++/102286 gcc/cp/ChangeLog: * call.cc (build_over_call): Fold more indirect refs for trivial assignment op. * class.cc (type_has_non_deleted_trivial_default_ctor): Create. * constexpr.cc (cxx_eval_call_expression): Start lifetime of union member before entering constructor. (cxx_eval_component_reference): Check against first member of value-initialised union. (cxx_eval_store_expression): Activate member for value-initialised union. Check for accessing inactive union member indirectly. * cp-tree.h (type_has_non_deleted_trivial_default_ctor): Forward declare. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-89336-3.C: Fix union initialisation. * g++.dg/cpp1y/constexpr-union6.C: New test. * g++.dg/cpp1y/constexpr-union7.C: New test. * g++.dg/cpp2a/constexpr-union2.C: New test. * g++.dg/cpp2a/constexpr-union3.C: New test. * g++.dg/cpp2a/constexpr-union4.C: New test. * g++.dg/cpp2a/constexpr-union5.C: New test. * g++.dg/cpp2a/constexpr-union6.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-19c++: Improve diagnostics for constexpr cast from void*Nathaniel Shead1-12/+79
This patch improves the errors given when casting from void* in C++26 to include the expected type if the types of the pointed-to objects were not similar. It also ensures (for all standard modes) that void* casts are checked even for DECL_ARTIFICIAL declarations, such as lifetime-extended temporaries, and is only ignored for cases where we know it's OK (e.g. source_location::current) or have no other choice (heap-allocated data). gcc/cp/ChangeLog: * constexpr.cc (is_std_source_location_current): New. (cxx_eval_constant_expression): Only ignore cast from void* for specific cases and improve other diagnostics. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-cast4.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Marek Polacek <polacek@redhat.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-17c++: Add missing auto_diagnostic_groups to constexpr.ccNathaniel Shead1-0/+9
gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_dynamic_cast_fn): Add missing auto_diagnostic_group. (cxx_eval_call_expression): Likewise. (diag_array_subscript): Likewise. (outside_lifetime_error): Likewise. (potential_constant_expression_1): Likewise. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Marek Polacek <polacek@redhat.com>
2023-10-16c++: fix truncated diagnostic in C++23 [PR111272]Marek Polacek1-1/+9
In C++23, since P2448, a constexpr function F that calls a non-constexpr function N is OK as long as we don't actually call F in a constexpr context. So instead of giving an error in maybe_save_constexpr_fundef, we only give an error when evaluating the call. Unfortunately, as shown in this PR, the diagnostic can be truncated: z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function because: 10 | constexpr Jam() { ft(); } | ^~~ ...because what? With this patch, we say: z.C:10:13: note: 'constexpr Jam::Jam()' is not usable as a 'constexpr' function because: 10 | constexpr Jam() { ft(); } | ^~~ z.C:10:23: error: call to non-'constexpr' function 'int Jam::ft()' 10 | constexpr Jam() { ft(); } | ~~^~ z.C:8:7: note: 'int Jam::ft()' declared here 8 | int ft() { return 42; } | ^~ Like maybe_save_constexpr_fundef, explain_invalid_constexpr_fn should also check the body of a constructor, not just the mem-initializer. PR c++/111272 gcc/cp/ChangeLog: * constexpr.cc (explain_invalid_constexpr_fn): Also check the body of a constructor in C++14 and up. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-diag1.C: New test.
2023-09-28Remove some unused poly_int variablesRichard Sandiford1-1/+0
Switching to default constructors for poly_int exposed some unused variables that weren't previously diagnosed. gcc/ * dwarf2out.cc (mem_loc_descriptor): Remove unused variables. * tree-affine.cc (expr_to_aff_combination): Likewise. gcc/cp/ * constexpr.cc (cxx_fold_indirect_ref): Remove unused variables. gcc/rust/ * backend/rust-constexpr.cc (rs_fold_indirect_ref): Remove unused variables.
2023-09-22c++: constexpr and designated initializerJason Merrill1-1/+1
The change of active member being non-constant (before C++20) results in a CONSTRUCTOR with a null value for the first field, don't crash. gcc/cp/ChangeLog: * constexpr.cc (free_constructor): Handle null ce->value. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-union7.C: New test.
2023-09-19c++: Move consteval folding to cp_fold_rMarek Polacek1-3/+20
In the review of P2564: <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628747.html> it turned out that in order to correctly handle an example in the paper, we should stop doing immediate evaluation in build_over_call and bot_replace, and instead do it in cp_fold_r. This patch does that. Another benefit is that this is a pretty significant simplification, at least in my opinion. Also, this fixes the c++/110997 ICE (but the test doesn't compile yet). The main drawback seems to be that cp_fold_r doesn't process uninstantiated templates. We still have to handle things like "false ? foo () : 1". To that end, I've added cp_fold_immediate, called on dead branches in cxx_eval_conditional_expression. You'll see that I've reintroduced ADDR_EXPR_DENOTES_CALL_P here. This is to detect *(&foo)) () (s.*&S::foo) () which were deemed ill-formed. gcc/cp/ChangeLog: * call.cc (build_over_call): Set ADDR_EXPR_DENOTES_CALL_P. Don't handle immediate_invocation_p here. * constexpr.cc (cxx_eval_call_expression): Use mce_true for DECL_IMMEDIATE_FUNCTION_P. (cxx_eval_conditional_expression): Call cp_fold_immediate. * cp-gimplify.cc (enum fold_flags): Add ff_fold_immediate. (maybe_replace_decl): Make static. (cp_fold_r): Expand immediate invocations. (cp_fold_immediate_r): New. (cp_fold_immediate): New. * cp-tree.h (ADDR_EXPR_DENOTES_CALL_P): Define. (cp_fold_immediate): Declare. * tree.cc (bot_replace): Don't handle immediate invocations here. libstdc++-v3/ChangeLog: * testsuite/20_util/allocator/105975.cc: Add dg-error. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if2.C: Add xfail. * g++.dg/cpp2a/consteval-memfn1.C: Adjust. * g++.dg/cpp2a/consteval11.C: Remove dg-message. * g++.dg/cpp2a/consteval3.C: Remove dg-message and dg-error. * g++.dg/cpp2a/consteval9.C: Remove dg-message. * g++.dg/cpp2a/consteval32.C: New test. * g++.dg/cpp2a/consteval33.C: New test. * g++.dg/cpp2a/consteval34.C: New test. * g++.dg/cpp2a/consteval35.C: New test.
2023-09-05c++: improve verify_constant diagnostic [PR91483]Marek Polacek1-1/+62
When verify_constant complains, it's pretty terse. Consider void test () { constexpr int i = 42; constexpr const int *p = &i; } where it says "'& i' is not a constant expression". OK, but why? With this patch, we say: b.C:5:28: error: '& i' is not a constant expression 5 | constexpr const int *p = &i; | ^~ b.C:5:28: note: pointer to 'i' is not a constant expression b.C:4:17: note: address of non-static constexpr variable 'i' may differ on each invocation of the enclosing function; add 'static' to give it a constant address 4 | constexpr int i = 42; | ^ | static which brings g++ on par with clang++. PR c++/91483 gcc/cp/ChangeLog: * constexpr.cc (verify_constant_explain_r): New. (verify_constant): Call it. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/constexpr3.C: New test.
2023-08-25OpenMP: Add OMP_STRUCTURED_BLOCK and GIMPLE_OMP_STRUCTURED_BLOCK.Sandra Loosemore1-0/+1
In order to detect invalid jumps in and out of intervening code in imperfectly-nested loops, the front ends need to insert some sort of marker to identify the structured block sequences that they push into the inner body of the loop. The error checking happens in the diagnose_omp_blocks pass, between gimplification and OMP lowering, so we need both GENERIC and GIMPLE representations of these markers. They are removed in OMP lowering so no subsequent passes need to know about them. This patch doesn't include any front-end changes to generate the new data structures. gcc/cp/ChangeLog * constexpr.cc (cxx_eval_constant_expression): Handle OMP_STRUCTURED_BLOCK. * pt.cc (tsubst_expr): Likewise. gcc/ChangeLog * doc/generic.texi (OpenMP): Document OMP_STRUCTURED_BLOCK. * doc/gimple.texi (GIMPLE instruction set): Add GIMPLE_OMP_STRUCTURED_BLOCK. (GIMPLE_OMP_STRUCTURED_BLOCK): New subsection. * gimple-low.cc (lower_stmt): Error on GIMPLE_OMP_STRUCTURED_BLOCK. * gimple-pretty-print.cc (dump_gimple_omp_block): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (pp_gimple_stmt_1): Likewise. * gimple-walk.cc (walk_gimple_stmt): Likewise. * gimple.cc (gimple_build_omp_structured_block): New. * gimple.def (GIMPLE_OMP_STRUCTURED_BLOCK): New. * gimple.h (gimple_build_omp_structured_block): Declare. (gimple_has_substatements): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (CASE_GIMPLE_OMP): Likewise. * gimplify.cc (is_gimple_stmt): Handle OMP_STRUCTURED_BLOCK. (gimplify_expr): Likewise. * omp-expand.cc (GIMPLE_OMP_STRUCTURED_BLOCK): Error on GIMPLE_OMP_STRUCTURED_BLOCK. * omp-low.cc (scan_omp_1_stmt): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (lower_omp_1): Likewise. (diagnose_sb_1): Likewise. (diagnose_sb_2): Likewise. * tree-inline.cc (remap_gimple_stmt): Handle GIMPLE_OMP_STRUCTURED_BLOCK. (estimate_num_insns): Likewise. * tree-nested.cc (convert_nonlocal_reference_stmt): Likewise. (convert_local_reference_stmt): Likewise. (convert_gimple_call): Likewise. * tree-pretty-print.cc (dump_generic_node): Handle OMP_STRUCTURED_BLOCK. * tree.def (OMP_STRUCTURED_BLOCK): New. * tree.h (OMP_STRUCTURED_BLOCK_BODY): New.
2023-07-27c++: constexpr empty subobject elision [PR110197]Patrick Palka1-7/+16
Now that init_subob_ctx no longer sets new_ctx.ctor for a subobject of empty type, it seems we need to ensure its callers also consistently omit entries in the parent ctx->ctor for such subobjects. We also need to allow cxx_eval_array_reference to synthesize an empty subobject even if the array CONSTRUCTOR has CONSTRUCTOR_NO_CLEARING set. PR c++/110197 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_array_reference): Allow synthesizing an empty subobject even if CONSTRUCTOR_NO_CLEARING is set. (cxx_eval_bare_aggregate): Set 'no_slot' to true more generally whenever new_ctx.ctor is set to NULL_TREE by init_subob_ctx, i.e. whenever initializing an subobject of empty type. (cxx_eval_vec_init_1): Define 'no_slot' as above and use it accordingly. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-empty18.C: New test. * g++.dg/cpp0x/constexpr-empty19.C: New test.
2023-07-25c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675]Nathaniel Shead1-42/+86
This adds rudimentary lifetime tracking in C++ constexpr contexts, allowing the compiler to report errors with using values after their backing has gone out of scope. We don't yet handle other ways of accessing values outside their lifetime (e.g. following explicit destructor calls). PR c++/96630 PR c++/98675 PR c++/70331 gcc/cp/ChangeLog: * constexpr.cc (constexpr_global_ctx::is_outside_lifetime): New function. (constexpr_global_ctx::get_value): Don't return expired values. (constexpr_global_ctx::get_value_ptr): Likewise. (constexpr_global_ctx::remove_value): Mark value outside lifetime. (outside_lifetime_error): New function. (cxx_eval_call_expression): No longer track save_exprs. (cxx_eval_loop_expr): Likewise. (cxx_eval_constant_expression): Add checks for outside lifetime values. Remove local variables at end of bind exprs, and temporaries after cleanup points. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-lifetime1.C: New test. * g++.dg/cpp1y/constexpr-lifetime2.C: New test. * g++.dg/cpp1y/constexpr-lifetime3.C: New test. * g++.dg/cpp1y/constexpr-lifetime4.C: New test. * g++.dg/cpp1y/constexpr-lifetime5.C: New test. * g++.dg/cpp1y/constexpr-lifetime6.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-07-25c++: Improve location information in constant evaluationNathaniel Shead1-1/+30
This patch updates 'input_location' during constant evaluation to ensure that errors in subexpressions that lack location information still provide accurate diagnostics. By itself this change causes some small regressions in diagnostic quality for circumstances where errors used 'input_location' but the location of the parent subexpression doesn't make sense, so this patch also includes a small diagnostic improvement to fix the most egregious case. gcc/cp/ChangeLog: * constexpr.cc (modifying_const_object_error): Find the source location of the const object's declaration. (cxx_eval_constant_expression): Update input_location to the location of the currently evaluated expression, if possible. libstdc++-v3/ChangeLog: * testsuite/25_algorithms/equal/constexpr_neg.cc: Update diagnostic locations. * testsuite/26_numerics/gcd/105844.cc: Likewise. * testsuite/26_numerics/lcm/105844.cc: Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-48089.C: Update diagnostic locations. * g++.dg/cpp0x/constexpr-70323.C: Likewise. * g++.dg/cpp0x/constexpr-70323a.C: Likewise. * g++.dg/cpp0x/constexpr-delete2.C: Likewise. * g++.dg/cpp0x/constexpr-diag3.C: Likewise. * g++.dg/cpp0x/constexpr-ice20.C: Likewise. * g++.dg/cpp0x/constexpr-mutable3.C: Likewise. * g++.dg/cpp0x/constexpr-recursion.C: Likewise. * g++.dg/cpp0x/overflow1.C: Likewise. * g++.dg/cpp1y/constexpr-89285.C: Likewise. * g++.dg/cpp1y/constexpr-89481.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const14.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const16.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const18.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const19.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const21.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const22.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const3.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const4.C: Likewise. * g++.dg/cpp1y/constexpr-tracking-const7.C: Likewise. * g++.dg/cpp1y/constexpr-union5.C: Likewise. * g++.dg/cpp1y/pr68180.C: Likewise. * g++.dg/cpp1z/constexpr-lambda6.C: Likewise. * g++.dg/cpp1z/constexpr-lambda8.C: Likewise. * g++.dg/cpp2a/bit-cast11.C: Likewise. * g++.dg/cpp2a/bit-cast12.C: Likewise. * g++.dg/cpp2a/bit-cast14.C: Likewise. * g++.dg/cpp2a/constexpr-98122.C: Likewise. * g++.dg/cpp2a/constexpr-dynamic17.C: Likewise. * g++.dg/cpp2a/constexpr-init1.C: Likewise. * g++.dg/cpp2a/constexpr-new12.C: Likewise. * g++.dg/cpp2a/constexpr-new3.C: Likewise. * g++.dg/cpp2a/constinit10.C: Likewise. * g++.dg/cpp2a/is-corresponding-member4.C: Likewise. * g++.dg/ext/constexpr-vla2.C: Likewise. * g++.dg/ext/constexpr-vla3.C: Likewise. * g++.dg/ubsan/pr63956.C: Likewise. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-07-25c++: fix ICE with constexpr ARRAY_REF [PR110382]Marek Polacek1-2/+11
This code in cxx_eval_array_reference has been hard to get right. In r12-2304 I added some code; in r13-5693 I removed some of it. Here the problematic line is "S s = arr[0];" which causes a crash on the assert in verify_ctor_sanity: gcc_assert (!ctx->object || !DECL_P (ctx->object) || ctx->global->get_value (ctx->object) == ctx->ctor); ctx->object is the VAR_DECL 's', which is correct here. The second line points to the problem: we replaced ctx->ctor in cxx_eval_array_reference: new_ctx.ctor = build_constructor (elem_type, NULL); // #1 which I think we shouldn't have; the CONSTRUCTOR we created in cxx_eval_constant_expression/DECL_EXPR new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL); had the right type. We still need #1 though. E.g., in constexpr-96241.C, we never set ctx.ctor/object before calling cxx_eval_array_reference, so we have to build a CONSTRUCTOR there. And in constexpr-101371-2.C we have a ctx.ctor, but it has the wrong type, so we need a new one. We can fix the problem by always clearing the object, and, as an optimization, only create/free a new ctor when actually needed. PR c++/110382 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_array_reference): Create a new constructor only when we don't already have a matching one. Clear the object when the type is non-scalar. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-110382.C: New test.
2023-07-21c++: fix ICE with is_really_empty_class [PR110106]Marek Polacek1-2/+3
is_really_empty_class is liable to crash when it gets an incomplete or dependent type. Since r11-557, we pass the yet-uninstantiated class type S<0> of the PARM_DECL s to is_really_empty_class -- because of the potential_rvalue_constant_expression -> is_rvalue_constant_expression change in cp_parser_constant_expression. Here we're not parsing a template so we did not check COMPLETE_TYPE_P as we should. It should work to complete the type before checking COMPLETE_TYPE_P. PR c++/110106 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1): Try to complete the type when !processing_template_decl. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept80.C: New test.
2023-07-18c++: constexpr bit_cast with empty fieldJason Merrill1-0/+9
The change to only cache constexpr calls that are reduced_constant_expression_p tripped on bit-cast3.C, which failed that predicate due to the presence of an empty field in the result of native_interpret_aggregate, which reduced_constant_expression_p rejects to avoid confusing output_constructor. This patch proposes to skip such fields in native_interpret_aggregate, since they aren't actually involved in the value representation. gcc/ChangeLog: * fold-const.cc (native_interpret_aggregate): Skip empty fields. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_bit_cast): Check that the result of native_interpret_aggregate doesn't need more evaluation.
2023-07-17c++: only cache constexpr calls that are constant exprsJason Merrill1-8/+9
In reviewing Nathaniel's patch for PR70331, it occurred to me that instead of looking for various specific problematic things in the result of a constexpr call to decide whether to cache it, we should use reduced_constant_expression_p. The change to that function is to avoid crashing on uninitialized objects of non-class type. In a trial version of this patch I checked to see what cases this stopped caching; most were instances of partially-initialized return values, which seem fine to not cache. Some were returning pointers to expiring local variables, which we definitely want not to cache. And one was bit-cast3.C, which will be handled in a follow-up patch. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Only cache reduced_constant_expression_p results. (reduced_constant_expression_p): Handle CONSTRUCTOR of scalar type. (cxx_eval_constant_expression): Fold vectors here. (cxx_eval_bare_aggregate): Not here.
2023-07-14c++: style tweakNathaniel Shead1-1/+1
At this point r == t, but it makes more sense to refer to t like all the other cases do. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Pass t to get_value. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-07-14c++: c++26 regression fixesJason Merrill1-11/+10
Apparently I wasn't actually running the testsuite in C++26 mode like I thought I was, so there were some failures I wasn't seeing. The constexpr hunk fixes regressions with the P2738 implementation; we still need to use the old handling for casting from void pointers to heap variables. PR c++/110344 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Move P2738 handling after heap handling. * name-lookup.cc (get_cxx_dialect_name): Add C++26. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-cast2.C: Adjust for P2738. * g++.dg/ipa/devirt-45.C: Handle -fimplicit-constexpr.
2023-06-27c++: C++26 constexpr cast from void* [PR110344]Jason Merrill1-0/+11
P2768 allows static_cast from void* to ob* in constant evaluation if the pointer does in fact point to an object of the appropriate type. cxx_fold_indirect_ref already does the work of finding such an object if it happens to be a subobject rather than the outermost object at that address, as in constexpr-voidptr2.C. P2768 PR c++/110344 gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Update __cpp_constexpr. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): In C++26, allow cast from void* to the type of a pointed-to object. gcc/testsuite/ChangeLog: * g++.dg/cpp26/constexpr-voidptr1.C: New test. * g++.dg/cpp26/constexpr-voidptr2.C: New test. * g++.dg/cpp26/feat-cxx26.C: New test.
2023-06-12c++: build initializer_list<string> in a loop [PR105838]Jason Merrill1-3/+3
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-06-11c++: unsynthesized defaulted constexpr fn [PR110122]Patrick Palka1-4/+10
In this other testcase from PR110122, during regeneration of the generic lambda with V=Bar{}, substitution followed by coerce_template_parms for A<V>'s template argument naturally yields a copy of V in terms of Bar's (implicitly) defaulted copy constructor. This however happens inside a template context so although we introduced a use of the copy constructor, mark_used didn't actually synthesize it, which causes subsequent constant evaluation of the template argument to fail with: nontype-class59.C: In instantiation of ‘void f() [with Bar V = Bar{Foo()}]’: nontype-class59.C:22:11: required from here nontype-class59.C:18:18: error: ‘constexpr Bar::Bar(const Bar&)’ used before its definition We already make sure to instantiate templated constexpr functions needed for constant evaluation (as per P0859R0). So this patch fixes this by making us synthesize defaulted constexpr functions needed for constant evaluation as well. PR c++/110122 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Synthesize defaulted functions needed for constant evaluation. (instantiate_cx_fn_r): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/nontype-class59.C: New test.
2023-05-10c++: be stricter about constinit [CWG2543]Jason Merrill1-0/+12
DR 2543 clarifies that constinit variables should follow the language, and diagnose non-constant initializers (according to [expr.const]) even if they can actually initialize the variables statically. DR 2543 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Preserve TARGET_EXPR flags. (potential_constant_expression_1): Check TARGET_EXPR_ELIDING_P. * typeck2.cc (store_init_value): Diagnose constinit sooner. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2543.C: New test.
2023-05-10c++: always check consteval addressJason Merrill1-7/+15
The restriction on the "permitted result of a constant expression" to not refer to an immediate function applies regardless of context. The previous code tried to only check in cases where we wouldn't get the check in cp_fold_r, but with the next patch I would need to add another case and it shouldn't be a problem to always check. We also shouldn't talk about immediate evaluation when we aren't dealing with one. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Always check for address of immediate fn. (maybe_constant_init_1): Evaluate PTRMEM_CST. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2478.C: Handle -fimplicit-constexpr. * g++.dg/cpp23/consteval-if12.C: Adjust diagnostics. * g++.dg/cpp2a/consteval20.C: Likewise. * g++.dg/cpp2a/consteval24.C: Likewise. * g++.dg/cpp2a/srcloc20.C: Likewise.
2023-05-07c++: potentiality of templated memfn call [PR109480]Patrick Palka1-26/+6
Here we're incorrectly deeming the templated call a.g() inside b's initializer as potentially constant, despite g being non-constexpr, which leads to us needlessly instantiating the initializer ahead of time and which subsequently triggers a bug in access checking deferral (to be fixed by the follow-up patch). This patch fixes this by calling get_fns earlier during CALL_EXPR potentiality checking so that when we extract a FUNCTION_DECL out of a templated member function call (whose overall callee is typically a COMPONENT_REF) we do the usual constexpr-eligibility checking for it. In passing, I noticed the nearby special handling of the object argument of a non-static member function call is effectively the same as the generic argument handling a few lines below. So this patch just gets rid of this special handling; otherwise we'd have to adapt it to handle templated versions of such calls. PR c++/109480 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Reorganize to call get_fns sooner. Remove special handling of the object argument of a non-static member function call. Remove dead store to 'fun'. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept59.C: Make e() constexpr so that the expected "without object" diagnostic isn't replaced by a "call to non-constexpr function" diagnostic. * g++.dg/template/non-dependent25.C: New test.
2023-05-02c++: look for empty base at specific offset [PR109678]Jason Merrill1-1/+1
While looking at the empty base handling for 109678, it occurred to me that we ought to be able to look for an empty base at a specific offset, not just in general. PR c++/109678 gcc/cp/ChangeLog: * cp-tree.h (lookup_base): Add offset parm. * constexpr.cc (cxx_fold_indirect_ref_1): Pass it. * search.cc (struct lookup_base_data_s): Add offset. (dfs_lookup_base): Handle it. (lookup_base): Pass it.
2023-05-02c++: std::variant slow to compile [PR109678]Jason Merrill1-10/+13
Here, when dealing with a class with a complex subobject structure, we would try and fail to find the relevant FIELD_DECL for an empty base before giving up. And we would do this at each level, in a combinatorially problematic way. Instead, we should check for an empty base first. PR c++/109678 gcc/cp/ChangeLog: * constexpr.cc (cxx_fold_indirect_ref_1): Handle empty base first. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/variant1.C: New test.
2023-04-15c++: constexpr aggregate destruction [PR109357]Jason Merrill1-4/+11
We were assuming that the result of evaluation of TARGET_EXPR_INITIAL would always be the new value of the temporary, but that's not necessarily true when the initializer is complex (i.e. target_expr_needs_replace). In that case evaluating the initializer initializes the temporary as a side-effect. PR c++/109357 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression) [TARGET_EXPR]: Check for complex initializer. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-dtor15.C: New test.
2023-03-16c++: maybe_constant_init and unevaluated operands [PR109030]Patrick Palka1-0/+4
This testcase in this PR (already fixed by r13-6526-ge4692319fd5fc7) demonstrates that maybe_constant_init can be called on an unevaluated operand (e.g. from massage_init_elt) so this entry point should also limit constant evaluation in that case, like maybe_constant_value does. PR c++/109030 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_init_1): For an unevaluated non-manifestly-constant operand, don't constant evaluate and instead call fold_to_constant as in maybe_constant_value. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-inst2.C: New test.
2023-03-15c++: ICE with constexpr lambda [PR107280]Marek Polacek1-1/+2
We crash here since r10-3661, the store_init_value hunk in particular. Before, we called cp_fully_fold_init, so e.g. {.str=VIEW_CONVERT_EXPR<char[8]>("")} was folded into {.str=""} but now we don't fold and keep the VCE around, and it causes trouble in cxx_eval_store_expression: in the !refs->is_empty () loop we descend on .str's initializer but since it's wrapped in a VCE, we skip the STRING_CST check and then crash on the CONSTRUCTOR_NO_CLEARING. PR c++/107280 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_store_expression): Strip location wrappers. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-lambda28.C: New test.
2023-03-07c++: noexcept and copy elision [PR109030]Marek Polacek1-1/+5
When processing a noexcept, constructors aren't elided: build_over_call has /* It's unsafe to elide the constructor when handling a noexcept-expression, it may evaluate to the wrong value (c++/53025). */ && (force_elide || cp_noexcept_operand == 0)) so the assert I added recently needs to be relaxed a little bit. PR c++/109030 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Relax assert. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept77.C: New test.
2023-03-07c++: error with constexpr operator() [PR107939]Marek Polacek1-2/+6
Similarly to PR107938, this also started with r11-557, whereby cp_finish_decl can call check_initializer even in a template for a constexpr initializer. Here we are rejecting extern const Q q; template<int> constexpr auto p = q(0); even though q has a constexpr operator(). It's deemed non-const by decl_maybe_constant_var_p because even though 'q' is const it is not of integral/enum type. If fun is not a function pointer, we don't know if we're using it as an lvalue or rvalue, so with this patch we pass 'any' for want_rval. With that, p_c_e/VAR_DECL doesn't flat out reject the underlying VAR_DECL. PR c++/107939 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Pass 'any' when recursing on a VAR_DECL and not a pointer to function. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/var-templ74.C: Remove dg-error. * g++.dg/cpp1y/var-templ77.C: New test.
2023-03-04c++: Don't defer local statics initialized with constant expressions [PR108702]Jakub Jelinek1-0/+19
The stmtexpr19.C testcase used to be rejected as it has a static variable in statement expression in constexpr context, but as that static variable is initialized by constant expression, when P2647R1 was implemented we agreed to make it valid. Now, as reported, the testcase compiles fine, but doesn't actually link because the static variable isn't defined anywhere, and with -flto ICEs because of this problem. This is because we never varpool_node::finalize_decl those vars, the constant expression in which the DECL_EXPR is present for the static VAR_DECL is folded (constant evaluated) into just the address of the VAR_DECL. Now, similar testcase included below (do we want to include it in the testsuite too?) works fine, because in cp_finish_decl -> make_rtl_for_nonlocal_decl we have since PR70353 fix: /* We defer emission of local statics until the corresponding DECL_EXPR is expanded. But with constexpr its function might never be expanded, so go ahead and tell cgraph about the variable now. */ defer_p = ((DECL_FUNCTION_SCOPE_P (decl) && !var_in_maybe_constexpr_fn (decl)) || DECL_VIRTUAL_P (decl)); and so don't defer them in constexpr/consteval functions. The following patch calls rest_of_decl_compilation which make_rtl_for_nonlocal_decl didn't call when encountering DECL_EXPRs of such vars during constant evaluation if they weren't finalized yet. 2023-03-04 Jakub Jelinek <jakub@redhat.com> PR c++/108702 * constexpr.cc: Include toplev.h. (cxx_eval_constant_expression) <case DECL_EXPR>: When seeing a local static initialized by constant expression outside of a constexpr function which has been deferred by make_rtl_for_nonlocal_decl, call rest_of_decl_compilation on it. * g++.dg/ext/stmtexpr19.C: Use dg-do link rather than dg-do compile.
2023-03-02c++: constant non-copy-init is manifestly constant [PR108243]Patrick Palka1-0/+2
According to [basic.start.static]/2 and [expr.const]/2, a variable with static storage duration initialized with a constant initializer has constant initialization, and such an initializer is manifestly constant-evaluated. For copy initialization, we're already getting this right because in that case check_initializer would consistently call store_init_value, which for TREE_STATIC variables calls fold_non_dependent_init with m_c_e=true. But for direct (or default) initialization, check_initializer doesn't always call store_init_value. We instead however always call maybe_constant_init from expand_default_init[1], albeit with m_c_e=false which means we don't get the "manifestly constant-evaluated" part right for non-copy-init. This patch fixes this by setting m_c_e=true in maybe_constant_init for static storage duration variables, mainly for benefit of the call to maybe_constant_init from expand_default_init. [1]: this maybe_constant_init call isn't reached in the copy-init case because there init is a CONSTRUCTOR rather than a TREE_LIST, and so we exit early from expand_default_init, returning an INIT_EXPR. This INIT_EXPR is ultimately what causes us to consistently hit the store_init_value code path from check_initializer in the copy-init case. PR c++/108243 gcc/cp/ChangeLog: * constexpr.cc (maybe_constant_init_1): Override manifestly_const_eval to true if is_static. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/is-constant-evaluated14.C: New test.
2023-03-01c++: can't eval PTRMEM_CST in incomplete class [PR107574]Marek Polacek1-1/+12
Here we're attempting to evaluate a PTRMEM_CST in a class that hasn't been completed yet, but that doesn't work: /* We can't lower this until the class is complete. */ if (!COMPLETE_TYPE_P (DECL_CONTEXT (member))) return cst; and then this unlowered PTRMEM_CST is used as EXPR in tree op1 = build_nop (ptrdiff_type_node, expr); and we crash in a subsequent cp_fold_convert which gets type=ptrdiff_type_node, expr=PTRMEM_CST and does else if (TREE_CODE (expr) == PTRMEM_CST && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type), PTRMEM_CST_CLASS (expr))) where TYPE_PTRMEM_CLASS_TYPE (type) is going to crash since the type is ptrdiff_type_node. We could just add a TYPE_PTRMEM_P check before accessing TYPE_PTRMEM_CLASS_TYPE but I think it's nicer to explain why we couldn't evaluate the expression. PR c++/107574 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Emit an error when a PTRMEM_CST cannot be evaluated. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/ptrmem-cst1.C: New test.