aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
AgeCommit message (Collapse)AuthorFilesLines
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-03-09c++: CTAD for less-specialized alias template [PR102529]Jason Merrill1-1/+3
The standard was unclear what happens with the transformation of a deduction guide if the initial template argument deduction fails for a reason other than not deducing all the arguments; my implementation assumed that the right thing was to give up on the deduction guide. But in consideration of CWG2664 this week I realized that we get a better result by just continuing with an empty set of deductions, so the alias deduction guide is the same as the original deduction guide plus the deducible constraint. DR 2664 PR c++/102529 gcc/cp/ChangeLog: * pt.cc (alias_ctad_tweaks): Continue after deduction failure. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2664.C: New test. * g++.dg/cpp2a/class-deduction-alias15.C: New test.
2023-03-09c++: fix alias CTAD [PR105841]Jason Merrill1-32/+101
In my initial implementation of alias CTAD, I described a couple of differences from the specification that I thought would not have a practical effect; this testcase demonstrates that I was wrong. One difference is resolved by the CPTK_IS_DEDUCIBLE commit; the other (adding too many of the alias template parameters to the new deduction guide) is fixed by this patch. PR c++/105841 gcc/cp/ChangeLog: * pt.cc (corresponding_template_parameter_list): Split out... (corresponding_template_parameter): ...from here. (find_template_parameters): Factor out... (find_template_parameter_info::find_in): ...this function. (find_template_parameter_info::find_in_recursive): New. (find_template_parameter_info::found): New. (alias_ctad_tweaks): Only add parms used in the deduced args. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-alias14.C: New test. Co-authored-by: Michael Spertus <mike@spertus.com>
2023-03-09c++: hide __is_deducible for GCC 13Jason Merrill1-1/+2
I want to have more discussion about the interface before claiming the __is_deducible name, so for GCC 13 make it internal-only. gcc/ChangeLog: * doc/extend.texi: Comment out __is_deducible docs. gcc/cp/ChangeLog: * cp-trait.def (IS_DEDUCIBLE): Add space to name. gcc/testsuite/ChangeLog: * g++.dg/ext/is_deducible1.C: Guard with __has_builtin (__is_deducible).
2023-03-09c++: add __is_deducible trait [PR105841]Jason Merrill8-16/+96
C++20 class template argument deduction for an alias template involves adding a constraint that the template arguments for the alias template can be deduced from the return type of the deduction guide for the underlying class template. In the standard, this is modeled as defining a class template with a partial specialization, but it's much more efficient to implement with a trait that directly tries to perform the deduction. The first argument to the trait is a template rather than a type, so various places needed to be adjusted to accommodate that. PR c++/105841 gcc/ChangeLog: * doc/extend.texi (Type Traits):: Document __is_deducible. gcc/cp/ChangeLog: * cp-trait.def (IS_DEDUCIBLE): New. * cxx-pretty-print.cc (pp_cxx_trait): Handle non-type. * parser.cc (cp_parser_trait): Likewise. * tree.cc (cp_tree_equal): Likewise. * pt.cc (tsubst_copy_and_build): Likewise. (type_targs_deducible_from): New. (alias_ctad_tweaks): Use it. * semantics.cc (trait_expr_value): Handle CPTK_IS_DEDUCIBLE. (finish_trait_expr): Likewise. * constraint.cc (diagnose_trait_expr): Likewise. * cp-tree.h (type_targs_deducible_from): Declare. gcc/testsuite/ChangeLog: * g++.dg/ext/is_deducible1.C: New test.
2023-03-08Daily bump.GCC Administrator1-0/+34
2023-03-07c++: static lambda tsubst [PR108526]Jason Merrill1-2/+2
A missed piece of the patch for static operator(): in tsubst_function_decl, we don't want to replace the first parameter with a new closure pointer if operator() is static. PR c++/108526 PR c++/106651 gcc/cp/ChangeLog: * pt.cc (tsubst_function_decl): Don't replace the closure parameter if DECL_STATIC_FUNCTION_P. gcc/testsuite/ChangeLog: * g++.dg/cpp23/static-operator-call5.C: Pass -g.
2023-03-07c++: -Wdangling-reference with reference wrapper [PR107532]Marek Polacek1-14/+84
Here, -Wdangling-reference triggers where it probably shouldn't, causing some grief. The code in question uses a reference wrapper with a member function returning a reference to a subobject of a non-temporary object: const Plane & meta = fm.planes().inner(); I've tried a few approaches, e.g., checking that the member function's return type is the same as the type of the enclosing class (which is the case for member functions returning *this), but that then breaks Wdangling-reference4.C with std::optional<std::string>. This patch adjusts do_warn_dangling_reference so that we look through reference wrapper classes (meaning, has a reference member and a constructor taking the same reference type, or is std::reference_wrapper or std::ranges::ref_view) and don't warn for them, supposing that the member function returns a reference to a non-temporary object. PR c++/107532 gcc/cp/ChangeLog: * call.cc (reference_like_class_p): New. (do_warn_dangling_reference): Add new bool parameter. See through reference_like_class_p. gcc/testsuite/ChangeLog: * g++.dg/warn/Wdangling-reference8.C: New test. * g++.dg/warn/Wdangling-reference9.C: New test.
2023-03-07c++: Fix up ICE in emit_support_tinfo_1 [PR109042]Jakub Jelinek2-3/+12
In my recent rtti.cc change I assumed when emitting the support tinfos that the tinfos for the fundamental types haven't been created yet. Normally (in libsupc++.a (fundamental_type_info.o)) that is the case, but as can be seen on the testcase, one can violate it by using typeid etc. in the same TU and do it before ~__fundamental_type_info () definition. The following patch fixes that by popping from unemitted_tinfo_decls only in the normal case when it is there, and treating non-NULL DECL_INITIAL on a tinfo node as indication that emit_tinfo_decl has processed it already. 2023-03-07 Jakub Jelinek <jakub@redhat.com> PR c++/109042 * rtti.cc (emit_support_tinfo_1): Don't assert that last unemitted_tinfo_decls element is tinfo, instead pop from it only in that case. * decl2.cc (c_parse_final_cleanups): Don't call emit_tinfo_decl for unemitted_tinfO_decls which have already non-NULL DECL_INITIAL. * g++.dg/rtti/pr109042.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-05Daily bump.GCC Administrator1-0/+9
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-04Daily bump.GCC Administrator1-0/+14
2023-03-03c++: thinko in extract_local_specs [PR108998]Patrick Palka1-1/+9
In order to fix PR100295, r13-4730-g18499b9f848707 attempted to make extract_local_specs walk the given pattern twice, ignoring unevaluated operands the first time around so that we prefer to process a local specialization in an evaluated context if it appears in one (we process each local specialization once even if it appears multiple times in the pattern). But there's a thinko in the patch, namely that we don't actually walk the pattern twice since we don't clear the visited set for the second walk (to avoid processing a local specialization twice) and so the root node (and any node leading up to an unevaluated operand) is considered visited already. So the patch effectively made extract_local_specs ignore unevaluated operands altogether, which this testcase demonstrates isn't quite safe (extract_local_specs never sees 'aa' and we don't record its local specialization, so later we try to specialize 'aa' on the spot with the args {{int},{17}} which causes us to nonsensically substitute its auto with 17.) This patch fixes this by refining the second walk to start from the trees we skipped over during the first walk. PR c++/108998 gcc/cp/ChangeLog: * pt.cc (el_data::skipped_trees): New data member. (extract_locals_r): Push to skipped_trees any unevaluated contexts that we skipped over. (extract_local_specs): For the second walk, start from each tree in skipped_trees. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-generic11.C: New test.
2023-03-03[c++] suppress redundant null-addr warn in pfn from pmfnAlexandre Oliva1-5/+12
When TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta, when we warn about comparing a pointer-to-member-function with NULL, we also warn about comparing the pointer-to-function extracted from it with NULL, which is redundant. Suppress the redundant warning. for gcc/cp/ChangeLog * typeck.cc (cp_build_binary_op): Suppress redundant warning for pfn null test in pmfn test with vbit-in-delta.
2023-03-03Daily bump.GCC Administrator1-0/+56
2023-03-03c++, v3: Emit fundamental tinfos for _Float16/decltype(0.0bf16) types on ↵Jakub Jelinek3-29/+37
ia32 with -mno-sse2 [PR108883] _Float16 and decltype(0.0bf16) types are on x86 supported only with -msse2. On x86_64 that is the default, but on ia32 it is not. We should still emit fundamental type tinfo for those types in libsupc++.a/libstdc++.*, regardless of whether libsupc++/libstdc++ is compiled with -msse2 or not, as user programs can be compiled with different ISA flags from libsupc++/libstdc++ and if they are compiled with -msse2 and use std::float16_t or std::bfloat16_t and need RTTI for it, it should work out of the box. Furthermore, libstdc++ ABI on ia32 shouldn't depend on whether the library is compiled with -mno-sse or -msse2. Unfortunately, just hacking up libsupc++ Makefile/configure so that a single source is compiled with -msse2 isn't appropriate, because that TU emits also code and the code should be able to run on CPUs which libstdc++ supports. We could add [[gnu::attribute ("no-sse2")]] there perhaps conditionally, but it all gets quite ugly. The following patch instead adds a target hook which allows the backend to temporarily tweak registered types such that emit_support_tinfos emits whatever is needed. Additionally, it makes emit_support_tinfos_1 call emit_tinfo_decl immediately, so that temporarily created dummy types for emit_support_tinfo purposes only can be nullified again afterwards. And removes the previous fallback_* types used for dfloat*_type_node tinfos even when decimal types aren't supported. 2023-03-03 Jakub Jelinek <jakub@redhat.com> PR target/108883 gcc/ * target.h (emit_support_tinfos_callback): New typedef. * targhooks.h (default_emit_support_tinfos): Declare. * targhooks.cc (default_emit_support_tinfos): New function. * target.def (emit_support_tinfos): New target hook. * doc/tm.texi.in (emit_support_tinfos): Document it. * doc/tm.texi: Regenerated. * config/i386/i386.cc (ix86_emit_support_tinfos): New function. (TARGET_EMIT_SUPPORT_TINFOS): Redefine. gcc/cp/ * cp-tree.h (enum cp_tree_index): Remove CPTI_FALLBACK_DFLOAT*_TYPE enumerators. (fallback_dfloat32_type, fallback_dfloat64_type, fallback_dfloat128_type): Remove. * rtti.cc (emit_support_tinfo_1): If not emitted already, call emit_tinfo_decl and remove from unemitted_tinfo_decls right away. (emit_support_tinfos): Move &dfloat*_type_node from fundamentals array into new fundamentals_with_fallback array. Call emit_support_tinfo_1 on elements of that array too, with the difference that if the type is NULL, use a fallback REAL_TYPE for it temporarily. Drop the !targetm.decimal_float_supported_p () handling. Call targetm.emit_support_tinfos at the end. * mangle.cc (write_builtin_type): Remove references to fallback_dfloat*_type. Handle bfloat16_type_node mangling.
2023-03-02c++: more mce_false folding from cp_fully_fold_init [PR108243]Patrick Palka1-5/+14
We should also fold the overall initializer passed to cp_fully_fold_init with mce_false, which allows folding of the copy-initialization of 'a1' in the below testcase (the initializer here is an AGGR_INIT_EXPR). Unfortunately this doesn't help with direct- or default-initialization because we don't call cp_fully_fold_init in that case, and even if we did the initializer in that case is expressed as a bare CALL_EXPR instead of an AGGR_INIT_EXPR, which cp_fully_fold_init can't really fold. PR c++/108243 PR c++/97553 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_fully_fold): Add an internal overload that additionally takes and propagate an mce_value parameter, and define the existing public overload in terms of it. (cp_fully_fold_init): Pass mce_false to cp_fully_fold. gcc/testsuite/ChangeLog: * g++.dg/opt/is_constant_evaluated3.C: New test.
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-02c++, debug: Fix up locus of DW_TAG_imported_module [PR108716]Jakub Jelinek1-0/+2
Before IMPORTED_DECL has been introduced in PR37410, we used to emit correct DW_AT_decl_line on DW_TAG_imported_module on the testcase below, after that change we haven't emitted it at all for a while and after some time started emitting incorrect locus, in particular the location of } closing the function. The problem is that while we have correct EXPR_LOCATION on the USING_STMT, when genericizing that USING_STMT into IMPORTED_DECL we don't copy the location to DECL_SOURCE_LOCATION, so it gets whatever input_location happens to be when it is created. 2023-03-02 Jakub Jelinek <jakub@redhat.com> PR debug/108716 * cp-gimplify.cc (cp_genericize_r) <case USING_STMT>: Set DECL_SOURCE_LOCATION on IMPORTED_DECL to expression location of USING_STMT or input_location. * g++.dg/debug/dwarf2/pr108716.C: New test.
2023-03-02c++: ICE with -Wmismatched-tags and member template [PR106259]Marek Polacek1-6/+24
-Wmismatched-tags warns about the (harmless) struct/class mismatch. For, e.g., template<typename T> struct A { }; class A<int> a; it works by adding A<T> to the class2loc hash table while parsing the class-head and then, while parsing the elaborate type-specifier, we add A<int>. At the end of c_parse_file we go through the table and warn about the class-key mismatches. In this PR we crash though; we have template<typename T> struct A { template<typename U> struct W { }; }; struct A<int>::W<int> w; // #1 where while parsing A and #1 we've stashed A<T> A<T>::W<U> A<int>::W<int> into class2loc. Then in class_decl_loc_t::diag_mismatched_tags TYPE is A<int>::W<int>, and specialization_of gets us A<int>::W<U>, which is not in class2loc, so we crash on gcc_assert (cdlguide). But it's OK not to have found A<int>::W<U>, we should just look one "level" up, that is, A<T>::W<U>. It's important to handle class specializations, so e.g. template<> struct A<char> { template<typename U> class W { }; }; where W's class-key is different than in the primary template above, so we should warn depending on whether we're looking into A<char> or into a different instantiation. PR c++/106259 gcc/cp/ChangeLog: * parser.cc (class_decl_loc_t::diag_mismatched_tags): If the first lookup of SPEC didn't find anything, try to look for most_general_template. gcc/testsuite/ChangeLog: * g++.dg/warn/Wmismatched-tags-11.C: New test.
2023-03-02openmp: Fix up error recovery for invalid structured bindings in OpenMP ↵Jakub Jelinek1-2/+5
range for loops [PR105839] The PR108503 temporary DECL_HAS_VALUE_EXPR_P clearing code can ICE during recovery, because cp_finish_decomp when it detects errors and reports them clears DECL_HAS_VALUE_EXPR_P, clears DECL_VALUE_EXPR and sets TREE_TYPE of the structured binding vars to error_mark_node. The PR108503 code had an assertion that DECL_HAS_VALUE_EXPR_P is set so that it can clear it and restore later. The following patch allows DECL_HAS_VALUE_EXPR_P to be unset if type is error_mark_node and doesn't set it again in that case. 2023-03-02 Jakub Jelinek <jakub@redhat.com> PR c++/105839 * parser.cc (cp_convert_omp_range_for): Allow in assert decomp_first_name without DECL_HAS_VALUE_EXPR_P if it has error_mark_node type. (cp_finish_omp_range_for): Don't set DECL_HAS_VALUE_EXPR_P back on decls which have error_mark_node type. * g++.dg/gomp/pr105839-1.C: New test. * g++.dg/gomp/pr105839-2.C: New test.
2023-03-02Daily bump.GCC Administrator1-0/+39
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.
2023-03-01c++: streamline tf_qualifying_scope usagePatrick Palka1-26/+17
This patch introduces a convenience wrapper tsubst_scope for tsubst'ing into a type with tf_qualifying_scope set, and makes suitable callers use it instead of explicitly setting tf_qualifying_scope. This patch also makes tsubst_copy immediately delegate to tsubst for all type trees, which allows tsubst_copy to be oblivious to the tf_qualifying_scope flag. gcc/cp/ChangeLog: * pt.cc (tsubst_scope): Define. (tsubst_decl) <case USING_DECL>: Call tsubst_scope instead of calling tsubst_scope with tf_qualifying_scope set. (tsubst_qualified_id): Call tsubst_scope instead of calling tsubst with tf_qualifying_scope set. (tsubst_copy): Immediately delegate to tsubst for all TYPE_P trees. Remove tf_qualifying_scope manipulation. <case SCOPE_REF>: Call tsubst_scope instead of calling tsubst with tf_qualifying_scope set.
2023-03-01c++: unevaluated array new-expr size constantness [PR108219]Patrick Palka2-5/+25
Here we're mishandling the unevaluated array new-expressions due to a supposed non-constant array size ever since r12-5253-g4df7f8c79835d569 made us no longer perform constant evaluation of non-manifestly-constant expressions within unevaluated contexts. This shouldn't make a difference here since the array sizes are constant literals, except they're expressed as NON_LVALUE_EXPR location wrappers around INTEGER_CST, wrappers which used to get stripped as part of constant evaluation and now no longer do. Moreover it means build_vec_init can't constant fold the MINUS_EXPR 'maxindex' passed from build_new_1 when in an unevaluated context (since it tries reducing it via maybe_constant_value called with mce_unknown). This patch fixes these issues by making maybe_constant_value (and fold_non_dependent_expr) try folding an unevaluated non-manifestly-constant operand via fold(), as long as it simplifies to a simple constant, rather than doing no simplification at all. This covers e.g. simple arithmetic and casts including stripping of location wrappers around INTEGER_CST. In passing, this patch also fixes maybe_constant_value to avoid constant evaluating an unevaluated operand when called with mce_false, by adjusting the early exit test appropriately. Co-authored-by: Jason Merrill <jason@redhat.com> PR c++/108219 PR c++/108218 gcc/cp/ChangeLog: * constexpr.cc (fold_to_constant): Define. (maybe_constant_value): Move up early exit test for unevaluated operands. Try reducing an unevaluated operand to a constant via fold_to_constant. (fold_non_dependent_expr_template): Add early exit test for CONSTANT_CLASS_P nodes. Try reducing an unevaluated operand to a constant via fold_to_constant. * cp-tree.h (fold_to_constant): Declare. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/new6.C: New test. * g++.dg/cpp2a/concepts-new1.C: New test.
2023-03-01c++: Don't recurse on DECL_INITIAL for DECL_EXPR on non-VAR_DECLs [PR108606]Jakub Jelinek1-1/+3
The r13-2965-g73d9b0e5947e16 change changed the line touched in this patch from return RECUR (tmp, want_rval); to return RECUR (DECL_INITIAL (tmp), want_rval); This is on DECL_EXPR handling code, where tmp can be lots of different trees and DECL_INITIAL unfortunately also means different things on different trees. It is the initializer on VAR_DECL, DECL_ARG_TYPE on PARM_DECLs (though those are unlikely to have DECL_EXPRs), for FUNCTION_DECLs the body, ..., USING_DECL_DECLS on USING_DECLs and DECL_FRIENDLIST on TYPE_DECLs. The testcase below ICEs because we have a DECL_EXPR for TYPE_DECL which has non-NULL DECL_FRIENDLIST and we certainly can't recurse on the friend list. The following patch will RECUR on DECL_INITIAL only for VAR_DECLs and for anything else just return true. 2023-03-01 Jakub Jelinek <jakub@redhat.com> PR c++/108606 * constexpr.cc (potential_constant_expression_1) <case DECL_EXPR>: Only recurse on DECL_INITIAL (tmp) if tmp is a VAR_DECL, otherwise just return true. * g++.dg/cpp1y/pr108606.C: New test.
2023-03-01Daily bump.GCC Administrator1-0/+15
2023-02-28c++: non-dependent variable template-id [PR108848]Patrick Palka2-23/+26
Here we're treating deeming the non-dependent variable template-id tag<int> as dependent ever since r226642 gave variable TEMPLATE_ID_EXPR an empty type, which causes the call to finish_template_variable from finish_id_expression_1 to be unreachable at template parse time. Thus we're led into thinking tag<int>.var<void> refers to a dependent name. This patch fixes this by making finish_id_expression_1 instantiate a variable template-id as long as it's not dependent according to the dependence test in lookup_and_finish_template_variable rather than according to type_dependent_expression_p. PR c++/108848 gcc/cp/ChangeLog: * pt.cc (finish_template_variable): Move dependence check to here from ... (lookup_and_finish_template_variable): ... here. * semantics.cc (finish_id_expression_1): Call finish_template_variable sooner, before (and regardless of) the type_dependent_expression_p test. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/noexcept1.C: Don't expect a bogus "different exception specifier" error. Expect a separate "not usable in a constant expression" error. * g++.dg/cpp1y/var-templ75.C: New test. * g++.dg/cpp1y/var-templ76.C: New test.
2023-02-28c++: variable template and targ deduction [PR108550]Marek Polacek1-0/+6
In this test, we get a bogus error because we failed to deduce the auto in constexpr auto is_pointer_v = is_pointer<Tp>::value; to bool. Then ensure_literal_type_for_constexpr_object thinks the object isn't literal and an error is reported. This is another case of the interaction between tf_partial and 'auto', where the auto was not reduced so the deduction failed. In more detail: we have Wrap1<int>() in the code and we need to perform OR -> fn_type_unification. The targ list is incomplete, so we do tsubst_flags_t ecomplain = complain | tf_partial | tf_fndecl_type; fntype = tsubst (TREE_TYPE (fn), explicit_targs, ecomplain, NULL_TREE); where TREE_TYPE (fn) is struct integral_constant <T402> (void). Then we substitute the return type, which results in tsubsting is_pointer_v<int>. is_pointer_v is a variable template with a placeholder type: template <class Tp> constexpr auto is_pointer_v = is_pointer<Tp>::value; so we find ourselves in lookup_and_finish_template_variable. tf_partial is still set, so finish_template_variable -> instantiate_template -> tsubst won't reduce the level of auto. But then we do mark_used which eventually calls do_auto_deduction which clears tf_partial, because we want to replace the auto now. But we hadn't reduced auto's level so this fails. And since we're not in an immediate context, we emit a hard error. I suppose that when we reach lookup_and_finish_template_variable it's probably time to clear tf_partial. (I added an assert and our testsuite doesn't have a test whereby we get to lookup_and_finish_template_variable while tf_partial is still active.) PR c++/108550 gcc/cp/ChangeLog: * pt.cc (lookup_and_finish_template_variable): Clear tf_partial. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/var-templ70.C: New test. * g++.dg/cpp1y/var-templ71.C: New test. * g++.dg/cpp1y/var-templ72.C: New test.
2023-02-21Daily bump.GCC Administrator1-0/+13
2023-02-20c++: ICE with -fno-elide-constructors and trivial fn [PR101073]Marek Polacek1-22/+3
In constexpr-nsdmi3.C, with -fno-elide-constructors, we don't elide the Y::Y(const Y&) call used to initialize o.c. So store_init_value -> cxx_constant_init must constexpr-evaluate the call to Y::Y(const Y&) in cxx_eval_call_expression. It's a trivial function, so we do the "Shortcut trivial constructor/op=" code and rather than evaluating the function, we just create an assignment o.c = *(const struct Y &) (const struct Y *) &(&<PLACEHOLDER_EXPR struct X>)->b which is a MODIFY_EXPR, so the preeval code in cxx_eval_store_expression clears .ctor and .object, therefore we can't replace the PLACEHOLDER_EXPR whereupon we crash at /* A placeholder without a referent. We can get here when checking whether NSDMIs are noexcept, or in massage_init_elt; just say it's non-constant for now. */ gcc_assert (ctx->quiet); The PLACEHOLDER_EXPR can also be on the LHS as in constexpr-nsdmi10.C. I don't think we can do much here, but I noticed that the whole trivial_fn_p (fun) block is only entered when -fno-elide-constructors. This is true since GCC 9; it wasn't easy to bisect what changes made it so, but r240845 is probably one of them. -fno-elide-constructors is an option for experiments only so it's not clear to me why we'd still want to shortcut trivial constructor/op=. I propose to remove the code and add a checking assert to make sure we're not getting a trivial_fn_p unless -fno-elide-constructors. PR c++/101073 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Replace shortcutting trivial constructor/op= with a checking assert. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-nsdmi3.C: New test. * g++.dg/cpp1y/constexpr-nsdmi10.C: New test.
2023-02-20c++: ICE with redundant capture [PR108829]Marek Polacek1-3/+6
Here we crash in is_capture_proxy: /* Location wrappers should be stripped or otherwise handled by the caller before using this predicate. */ gcc_checking_assert (!location_wrapper_p (decl)); We only crash with the redundant capture: int abyPage = [=, abyPage] { ... } because prune_lambda_captures is only called when there was a default capture, and with [=] only abyPage won't be in LAMBDA_EXPR_CAPTURE_LIST. The problem is that LAMBDA_CAPTURE_EXPLICIT_P wasn't propagated correctly and so var_to_maybe_prune proceeded where it shouldn't. Co-Authored by: Patrick Palka <ppalka@redhat.com> PR c++/108829 gcc/cp/ChangeLog: * pt.cc (prepend_one_capture): Set LAMBDA_CAPTURE_EXPLICIT_P. (tsubst_lambda_expr): Pass LAMBDA_CAPTURE_EXPLICIT_P to prepend_one_capture. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-108829-2.C: New test. * g++.dg/cpp0x/lambda/lambda-108829.C: New test.
2023-02-19Daily bump.GCC Administrator1-0/+13
2023-02-18c++: static_assert (false) in template [DR2518]Jason Merrill1-7/+10
For a long time, people have expected to be able to write static_assert (false) in a template and only have it diagnosed if the template is instantiated, but we (and other implementations) gave an error about the uninstantiated template because the standard says that if no valid instantiation of the template is possible, the program is ill-formed, no diagnostic required, and we try to diagnose IFNDR things when feasible. At the meeting last week we were looking at CWG2518, which wanted to specify that an implementation must not accept a program containing a failing #error or static_assert. We also looked at P2593, which proposed allowing static_assert in an uninstantiated template. We ended up combining these two in order to avoid requiring implementations to reject programs with static_assert (false) in uninstantiated templates. The committee accepted this as a DR, so I'm making the change to all standard modes. This behavior was also conformant previously, since no diagnostic was required in this case. We continue to diagnose non-constant or otherwise ill-formed conditions, so no changes to existing tests were needed. DR 2518 PR c++/52809 PR c++/53638 PR c++/87389 PR c++/89741 PR c++/92099 PR c++/104041 PR c++/104691 gcc/cp/ChangeLog: * semantics.cc (finish_static_assert): Don't diagnose in template context. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2518.C: New test.
2023-02-18Daily bump.GCC Administrator1-0/+56
2023-02-17c++: speculative constexpr and is_constant_evaluated [PR108243]Patrick Palka1-42/+98
This PR illustrates that __builtin_is_constant_evaluated currently acts as an optimization barrier for our speculative constexpr evaluation, since we don't want to prematurely fold the builtin to false before the expression in question undergoes manifestly constant evaluation if appropriate (in which case the builtin must instead be folded to true). This patch fixes this by permitting __builtin_is_constant_evaluated to get folded as false at appropiate points, namely during cp_fold_function and cp_fully_fold_init where we know we're done with manifestly constant evaluation. The function cp_fold gets a flags parameter that controls whether we pass mce_false or mce_unknown to maybe_constant_value when folding a CALL_EXPR. PR c++/108243 PR c++/97553 gcc/cp/ChangeLog: * cp-gimplify.cc (enum fold_flags): Define. (fold_flags_t): Declare. (cp_fold_data::genericize): Replace this data member with ... (cp_fold_data::fold_flags): ... this. (cp_fold_r): Adjust use of cp_fold_data and calls to cp_fold. (cp_fold_function): Likewise. (cp_fold_maybe_rvalue): Add an internal overload that additionally takes and propagates a fold_flags_t parameter, and define the existing public overload in terms of it. (cp_fold_rvalue): Likewise. (cp_fully_fold_init): Adjust use of cp_fold_data. (fold_cache): Replace with ... (fold_caches): ... this 2-element array of caches. (get_fold_cache): Define. (clear_fold_cache): Adjust. (cp_fold): Add fold_flags_t parameter. Use get_fold_cache. Pass flags to calls to cp_fold, cp_fold_rvalue and cp_fold_maybe_rvalue. <case CALL_EXPR>: If ff_mce_false is set, fold __builtin_is_constant_evaluated to false and pass mce_false to maybe_constant_value. gcc/testsuite/ChangeLog: * g++.dg/opt/is_constant_evaluated1.C: New test. * g++.dg/opt/is_constant_evaluated2.C: New test.
2023-02-17c++: make manifestly_const_eval tri-statePatrick Palka5-35/+55
This patch converts the constexpr machinery's manifestly_const_eval flag into a tri-state enum to allow us to express wanting to fold __builtin_is_constant_evaluated to false via speculative constexpr evaluation. For now, only the maybe_constant_value entry point is changed to take this enum; the others continue to take bool. The subsequent patch will teach cp_fold (which uses maybe_constant_value) to fold the builtin to false when called from cp_fold_function and cp_fully_fold_init. gcc/cp/ChangeLog: * constexpr.cc (constexpr_call::manifestly_const_eval): Give it type int instead of bool. (constexpr_ctx::manifestly_const_eval): Give it type mce_value instead of bool. (cxx_eval_builtin_function_call): Adjust after making manifestly_const_eval tri-state. (cxx_eval_call_expression): Likewise. (cxx_eval_binary_expression): Likewise. (cxx_eval_conditional_expression): Likewise. (cxx_eval_constant_expression): Likewise. (cxx_eval_outermost_constant_expr): Likewise. (cxx_constant_value): Likewise. (cxx_constant_dtor): Likewise. (maybe_constant_value): Give manifestly_const_eval parameter type mce_value instead of bool and adjust accordingly. (fold_non_dependent_expr_template): Adjust call to cxx_eval_outermost_constant_expr. (fold_non_dependent_expr): Likewise. (maybe_constant_init_1): Likewise. * constraint.cc (satisfy_atom): Adjust call to maybe_constant_value. * cp-tree.h (enum class mce_value): Define. (maybe_constant_value): Adjust manifestly_const_eval parameter type and default argument. * decl.cc (compute_array_index_type_loc): Adjust call to maybe_constant_value. * pt.cc (convert_nontype_argument): Likewise.
2023-02-17Daily bump.GCC Administrator1-0/+31
2023-02-16c++: TYPENAME_TYPE lookup ignoring non-types [PR107773]Patrick Palka4-30/+42
Currently when resolving a TYPENAME_TYPE for 'typename T::m' via make_typename_type, we consider only type bindings of 'm' and ignore non-type ones. But [temp.res.general]/3 says, in a note, "the usual qualified name lookup ([basic.lookup.qual]) applies even in the presence of 'typename'", and qualified name lookup doesn't discriminate between type and non-type bindings. So when resolving such a TYPENAME_TYPE we want the lookup to consider all bindings. An exception is when we have a TYPENAME_TYPE corresponding to the qualifying scope of the :: scope resolution operator, such as 'T::type' in 'T::type::m'. In that case, [basic.lookup.qual]/1 applies, and lookup for such a TYPENAME_TYPE must ignore non-type bindings. So in order to correctly handle all cases, make_typename_type needs an additional flag controlling whether to restrict the lookup. To that end this patch adds a new tsubst flag tf_qualifying_scope denoting whether we're substituting the LHS of the :: operator, which make_typename_type will look for to conditionally restrict the lookup to type bindings (by default we want to consider all bindings). So in contexts such as substituting into the scope of TYPENAME_TYPE, SCOPE_REF or USING_DECL we simply pass tf_qualifying_scope to the relevant tsubst / tsubst_copy call, and if that scope is a TYPENAME_TYPE then make_typename_type will restrict the lookup accordingly. This flag is intended to apply only to overall scope (TYPENAME_TYPE or not) so we must be careful to clear the flag to avoid propagating it when recursing into sub-trees of the scope. PR c++/107773 gcc/cp/ChangeLog: * cp-tree.h (enum tsubst_flags): New flag tf_qualifying_scope. * decl.cc (make_typename_type): Use lookup_member instead of lookup_field. If tf_qualifying_scope is set, pass want_type=true instead of =false to lookup_member. Generalize format specifier in diagnostic to handle both type and non-type bindings. * pt.cc (tsubst_aggr_type_1): Clear tf_qualifying_scope. Tidy the function. (tsubst_decl) <case USING_DECL>: Set tf_qualifying_scope when substituting USING_DECL_SCOPE. (tsubst): Clear tf_qualifying_scope right away and remember if it was set. Do the same for tf_tst_ok sooner. <case TYPENAME_TYPE>: Set tf_qualifying_scope when substituting TYPE_CONTEXT. Pass tf_qualifying_scope to make_typename_type if it was set. (tsubst_qualified_id): Set tf_qualifying_scope when substituting the scope. (tsubst_copy): Clear tf_qualifying_scope and remember if it was set. <case SCOPE_REF>: Set tf_qualifying_scope when substituting the scope. <case *_TYPE>: Pass tf_qualifying_scope to tsubst if it was set. * search.cc (lookup_member): Document default argument. gcc/testsuite/ChangeLog: * g++.dg/template/typename24.C: New test. * g++.dg/template/typename25.C: New test. * g++.dg/template/typename25a.C: New test. * g++.dg/template/typename26.C: New test.
2023-02-16don't declare header-defined functions both static and inlinePatrick Palka1-1/+1
Many functions defined in our headers are declared 'static inline' which is a C idiom whose use predates our move to C++ as the implementation language. But in C++ the inline keyword is more than just a compiler hint, and is sufficient to give the function the intended semantics. In fact declaring a function both static and inline is a pessimization since static effectively disables the desired definition merging behavior enabled by inline, and is also a source of (harmless) ODR violations when a static inline function gets called from a non-static inline one (such as tree_operand_check calling tree_operand_length). This patch mechanically fixes the vast majority of occurrences of this anti-pattern throughout the compiler's headers via the command line sed -i 's/^static inline/inline/g' gcc/*.h gcc/*/*.h There's also a manual change to remove the redundant declarations of is_ivar and lookup_category in gcc/objc/objc-act.cc which would otherwise conflict with their modified definitions in objc-act.h (due to the difference in staticness). Besides fixing some ODR violations, this speeds up stage1 cc1plus by about 2% and reduces the size of its text segment by 1.5MB. gcc/ChangeLog: * addresses.h: Mechanically drop 'static' from 'static inline' functions via s/^static inline/inline/g. * asan.h: Likewise. * attribs.h: Likewise. * basic-block.h: Likewise. * bitmap.h: Likewise. * cfghooks.h: Likewise. * cfgloop.h: Likewise. * cgraph.h: Likewise. * cselib.h: Likewise. * data-streamer.h: Likewise. * debug.h: Likewise. * df.h: Likewise. * diagnostic.h: Likewise. * dominance.h: Likewise. * dumpfile.h: Likewise. * emit-rtl.h: Likewise. * except.h: Likewise. * expmed.h: Likewise. * expr.h: Likewise. * fixed-value.h: Likewise. * gengtype.h: Likewise. * gimple-expr.h: Likewise. * gimple-iterator.h: Likewise. * gimple-predict.h: Likewise. * gimple-range-fold.h: Likewise. * gimple-ssa.h: Likewise. * gimple.h: Likewise. * graphite.h: Likewise. * hard-reg-set.h: Likewise. * hash-map.h: Likewise. * hash-set.h: Likewise. * hash-table.h: Likewise. * hwint.h: Likewise. * input.h: Likewise. * insn-addr.h: Likewise. * internal-fn.h: Likewise. * ipa-fnsummary.h: Likewise. * ipa-icf-gimple.h: Likewise. * ipa-inline.h: Likewise. * ipa-modref.h: Likewise. * ipa-prop.h: Likewise. * ira-int.h: Likewise. * ira.h: Likewise. * lra-int.h: Likewise. * lra.h: Likewise. * lto-streamer.h: Likewise. * memmodel.h: Likewise. * omp-general.h: Likewise. * optabs-query.h: Likewise. * optabs.h: Likewise. * plugin.h: Likewise. * pretty-print.h: Likewise. * range.h: Likewise. * read-md.h: Likewise. * recog.h: Likewise. * regs.h: Likewise. * rtl-iter.h: Likewise. * rtl.h: Likewise. * sbitmap.h: Likewise. * sched-int.h: Likewise. * sel-sched-ir.h: Likewise. * sese.h: Likewise. * sparseset.h: Likewise. * ssa-iterators.h: Likewise. * system.h: Likewise. * target-globals.h: Likewise. * target.h: Likewise. * timevar.h: Likewise. * tree-chrec.h: Likewise. * tree-data-ref.h: Likewise. * tree-iterator.h: Likewise. * tree-outof-ssa.h: Likewise. * tree-phinodes.h: Likewise. * tree-scalar-evolution.h: Likewise. * tree-sra.h: Likewise. * tree-ssa-alias.h: Likewise. * tree-ssa-live.h: Likewise. * tree-ssa-loop-manip.h: Likewise. * tree-ssa-loop.h: Likewise. * tree-ssa-operands.h: Likewise. * tree-ssa-propagate.h: Likewise. * tree-ssa-sccvn.h: Likewise. * tree-ssa.h: Likewise. * tree-ssanames.h: Likewise. * tree-streamer.h: Likewise. * tree-switch-conversion.h: Likewise. * tree-vectorizer.h: Likewise. * tree.h: Likewise. * wide-int.h: Likewise. gcc/c-family/ChangeLog: * c-common.h: Mechanically drop static from static inline functions via s/^static inline/inline/g. gcc/c/ChangeLog: * c-parser.h: Mechanically drop static from static inline functions via s/^static inline/inline/g. gcc/cp/ChangeLog: * cp-tree.h: Mechanically drop static from static inline functions via s/^static inline/inline/g. gcc/fortran/ChangeLog: * gfortran.h: Mechanically drop static from static inline functions via s/^static inline/inline/g. gcc/jit/ChangeLog: * jit-dejagnu.h: Mechanically drop static from static inline functions via s/^static inline/inline/g. * jit-recording.h: Likewise. gcc/objc/ChangeLog: * objc-act.h: Mechanically drop static from static inline functions via s/^static inline/inline/g. * objc-map.h: Likewise. * objc-act.cc: Remove the redundant redeclarations of is_ivar and lookup_category.
2023-02-15Daily bump.GCC Administrator1-0/+5
2023-02-14c++: fix ICE in joust_maybe_elide_copy [PR106675]Marek Polacek1-0/+2
joust_maybe_elide_copy checks that the last conversion in the ICS for the first argument is ck_ref_bind, which is reasonable, because we've checked that we're dealing with a copy/move constructor. But it can also happen that we couldn't figure out which conversion function is better to convert the argument, as in this testcase: joust couldn't decide if we should go with operator foo &() or operator foo const &() so we get a ck_ambig, which then upsets joust_maybe_elide_copy. Since a ck_ambig can validly occur, I think we should just return early, as in the patch below. PR c++/106675 gcc/cp/ChangeLog: * call.cc (joust_maybe_elide_copy): Return false for ck_ambig. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/overload-conv-5.C: New test.
2023-02-10Daily bump.GCC Administrator1-0/+18
2023-02-09c++: ICE initing lifetime-extended constexpr var [PR107079]Marek Polacek1-1/+1
We ICE on the simple: struct X { const X* x = this; }; constexpr const X& x = X{}; where store_init_value initializes 'x' with &TARGET_EXPR <D.2768, {.x=(const struct X *) &<PLACEHOLDER_EXPR struct X>}> but we must lifetime-extend via extend_ref_init_temps and we get _ZGR1x_.x = (const struct X *) &<PLACEHOLDER_EXPR struct X> >>>;, (const struct X &) &_ZGR1x_; Since 'x' was declared constexpr, we do cxx_constant_init and we hit the preeval code added in r269003 while evaluating the INIT_EXPR: _ZGR1x_.x = (const struct X *) &<PLACEHOLDER_EXPR struct X> >>> but we have no ctx.ctor or ctx.object here so lookup_placeholder won't find anything that could replace X and we ICE on 7861 /* A placeholder without a referent. We can get here when 7862 checking whether NSDMIs are noexcept, or in massage_init_elt; 7863 just say it's non-constant for now. */ 7864 gcc_assert (ctx->quiet); because cxx_constant_init means !ctx->quiet. It's not correct that there isn't a referent. I think the following patch is a pretty straightforward fix: pass the _ZGR var down to maybe_constant_init so that it can replace the PLACEHOLDER_EXPR with _ZGR1x_. The commented assert in the test doesn't pass: we complain that _ZGR1x_ isn't a constexpr variable because we don't implement DR2126 (PR101588). PR c++/107079 gcc/cp/ChangeLog: * call.cc (set_up_extended_ref_temp): Pass var to maybe_constant_init. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-nsdmi2.C: New test.
2023-02-09OpenMP: Parse align clause in allocate directive in C/C++Tobias Burnus1-17/+80
gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_allocate): Parse align clause and check for restrictions. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_allocate): Parse align clause and check for restrictions. gcc/testsuite/ChangeLog: * c-c++-common/gomp/allocate-5.c: Extend for align clause.
2023-02-09c++: Mangle EXCESS_PRECISION_EXPR <REAL_CST> as fold_convert REAL_CST [PR108698]Jakub Jelinek1-0/+8
For standard excess precision, like the C FE we parse floating point constants as EXCESS_PRECISION_EXPR of promoted REAL_CST rather than the nominal REAL_CST, and as the following testcase shows the constants might need mangling. The following patch mangles those as fold_convert of the REAL_CST to EXCESS_PRECISION_EXPR type, i.e. how they were mangled before. I'm not really sure EXCESS_PRECISION_EXPR can appear elsewhere in expressions that would need mangling, tried various testcases but haven't managed to come up with one. If that is possible, we'd keep ICEing on it without/with this patch, and the big question is how to mangle those; they could be mangled as casts from the promoted type back to nominal, but then in the mangled expressions one could see the effects of excess precision. Until we have a reproducer, that is just theoretical though. 2023-02-09 Jakub Jelinek <jakub@redhat.com> PR c++/108698 * mangle.cc (write_expression, write_template_arg): Handle EXCESS_PRECISION_EXPR with REAL_CST operand as write_template_arg_literal on fold_convert of the REAL_CST to EXCESS_PRECISION_EXPR type. * g++.dg/cpp0x/pr108698.C: New test.
2023-02-07Daily bump.GCC Administrator1-0/+12
2023-02-05c++: equivalence of non-dependent calls [PR107461]Patrick Palka3-6/+21
After r13-5684-g59e0376f607805 the (pruned) callee of a non-dependent CALL_EXPR is a bare FUNCTION_DECL rather than ADDR_EXPR of FUNCTION_DECL. This innocent change revealed that cp_tree_equal doesn't first check dependence of a CALL_EXPR before treating a FUNCTION_DECL callee as a dependent name, which leads to us incorrectly accepting the first two testcases below and rejecting the third: * In the first testcase, cp_tree_equal incorrectly returns true for the two non-dependent CALL_EXPRs f(0) and f(0) (whose CALL_EXPR_FN are different FUNCTION_DECLs) which causes us to treat #2 as a redeclaration of #1. * Same issue in the second testcase, for f<int*>() and f<char>(). * In the third testcase, cp_tree_equal incorrectly returns true for f<int>() and f<void(*)(int)>() which causes us to conflate the two dependent specializations A<decltype(f<int>()(U()))> and A<decltype(f<void(*)(int)>()(U()))>. This patch fixes this by making called_fns_equal treat two callees as dependent names only if the overall CALL_EXPRs are dependent, via a new convenience function call_expr_dependent_name that is like dependent_name but also checks dependence of the overall CALL_EXPR. PR c++/107461 gcc/cp/ChangeLog: * cp-tree.h (call_expr_dependent_name): Declare. * pt.cc (iterative_hash_template_arg) <case CALL_EXPR>: Use call_expr_dependent_name instead of dependent_name. * tree.cc (call_expr_dependent_name): Define. (called_fns_equal): Adjust to take two CALL_EXPRs instead of CALL_EXPR_FNs thereof. Use call_expr_dependent_name instead of dependent_name. (cp_tree_equal) <case CALL_EXPR>: Adjust call to called_fns_equal. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/overload5.C: New test. * g++.dg/cpp0x/overload5a.C: New test. * g++.dg/cpp0x/overload6.C: New test.