aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
AgeCommit message (Collapse)AuthorFilesLines
2022-10-11c++ modules: ICE with templated friend and std namespace [PR100134]Patrick Palka1-0/+8
The function depset::hash::add_binding_entity has an assert verifying that if a namespace contains an exported entity, then the namespace must have been opened in the module purview: if (data->hash->add_namespace_entities (decl, data->partitions)) { /* It contains an exported thing, so it is exported. */ gcc_checking_assert (DECL_MODULE_PURVIEW_P (decl)); DECL_MODULE_EXPORT_P (decl) = true; } We're tripping over this assert in the below testcase because by instantiating and exporting std::A<int>, we in turn define and export the hidden friend std::f(A<int>) without ever having opened the enclosing namespace std within the module purview, and thus DECL_MODULE_PURVIEW_P for std is false. It's important that the enclosing namespace is std here: if we use a different namespace then the ICE disappears. This probably has something to do with us predefining std via push_namespace from cxx_init_decl_processing (which makes it look like we've opened it within the TU), whereas with another namespace we would instead lazily create its NAMESPACE_DECL from add_imported_namespace. Since templated friend functions are special in that they give us a way to introduce a namespace-scope function without having to explicitly open the namespace, this patch proposes to fix this ICE by propagating DECL_MODULE_PURVIEW_P from the introduced function to the enclosing namespace during tsubst_friend_function. PR c++/100134 gcc/cp/ChangeLog: * pt.cc (tsubst_friend_function): Propagate DECL_MODULE_PURVIEW_P from the introduced namespace-scope function to the namespace. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-8_a.H: New test. * g++.dg/modules/tpl-friend-8_b.C: New test.
2022-10-06c++: remove optimize_specialization_lookup_pPatrick Palka1-117/+40
Roughly speaking, optimize_specialization_lookup_p returns true for a non-template member function of a class template, e.g. template<class T> struct A { int f(); }; The idea behind the optimization guarded by this predicate is that if we want to look up the specialization A<T>::f [with T=int], then we can just do a name lookup for f in A<int> and avoid having to add a spec_entry for f in the decl_specializations table. But the benefit of this optimization seems questionable because in order to do the name lookup we first need to look up A<T> [with T=int] in the type_specializations table, which is as expensive as the decl_specializations lookup we're avoiding. And according to some experiments (using stdc++.h, range-v3 and libstdc++ tests) the compiler is slightly (<1%) _faster_ if we disable this optimization. Additionally, this optimization means we won't record an explicit specialization in decl_specializations for such a template either, which is an unfortunate inconsistency that apparently breaks the below modules testcase. So since this optimization doesn't improve performance, and complicates the explicit specialization story which causes issues with modules, this patch proposes to remove it. gcc/cp/ChangeLog: * pt.cc (optimize_specialization_lookup_p): Remove. (retrieve_specialization): Assume the above returns false and simplify accordingly. (register_specialization): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/indirect-3_b.C: Expect that the entity foo::TPL<0>::frob is tagged as a specialization instead of as a declaration. * g++.dg/modules/tpl-spec-8_a.H: New test. * g++.dg/modules/tpl-spec-8_b.C: New test.
2022-10-06c++, c: Implement C++23 P1774R8 - Portable assumptions [PR106654]Jakub Jelinek1-0/+27
The following patch implements C++23 P1774R8 - Portable assumptions paper, by introducing support for [[assume (cond)]]; attribute for C++. In addition to that the patch adds [[gnu::assume (cond)]]; and __attribute__((assume (cond))); support to both C and C++. As described in C++23, the attribute argument is conditional-expression rather than the usual assignment-expression for attribute arguments, the condition is contextually converted to bool (for C truthvalue conversion is done on it) and is never evaluated at runtime. For C++ constant expression evaluation, I only check the simplest conditions for undefined behavior, because otherwise I'd need to undo changes to *ctx->global which happened during the evaluation (but I believe the spec allows that and we can further improve later). The patch uses a new internal function, .ASSUME, to hold the condition in the FEs. At gimplification time, if the condition is simple/without side-effects, it is gimplified as if (cond) ; else __builtin_unreachable (); and otherwise for now dropped on the floor. The intent is to incrementally outline the conditions into separate artificial functions and use .ASSUME further to tell the ranger and perhaps other optimization passes about the assumptions, as detailed in the PR. When implementing it, I found that assume entry hasn't been added to https://eel.is/c++draft/cpp.cond#6 Jonathan said he'll file a NB comment about it, this patch assumes it has been added into the table as 202207L when the paper has been voted in. With the attributes for both C/C++, I'd say we don't need to add __builtin_assume with similar purpose, especially when __builtin_assume in LLVM is just weird. It is strange for side-effects in function call's argument not to be evaluated, and LLVM in that case (annoyingly) warns and ignores the side-effects (but doesn't do then anything with it), if there are no side-effects, it will work like our if (!cond) __builtin_unreachable (); 2022-10-06 Jakub Jelinek <jakub@redhat.com> PR c++/106654 gcc/ * internal-fn.def (ASSUME): New internal function. * internal-fn.h (expand_ASSUME): Declare. * internal-fn.cc (expand_ASSUME): Define. * gimplify.cc (gimplify_call_expr): Gimplify IFN_ASSUME. * fold-const.h (simple_condition_p): Declare. * fold-const.cc (simple_operand_p_2): Rename to ... (simple_condition_p): ... this. Remove forward declaration. No longer static. Adjust function comment and fix a typo in it. Adjust recursive call. (simple_operand_p): Adjust function comment. (fold_truth_andor): Adjust simple_operand_p_2 callers to call simple_condition_p. * doc/extend.texi: Document assume attribute. Move fallthrough attribute example to its section. gcc/c-family/ * c-attribs.cc (handle_assume_attribute): New function. (c_common_attribute_table): Add entry for assume attribute. * c-lex.cc (c_common_has_attribute): Handle __have_cpp_attribute (assume). gcc/c/ * c-parser.cc (handle_assume_attribute): New function. (c_parser_declaration_or_fndef): Handle assume attribute. (c_parser_attribute_arguments): Add assume_attr argument, if true, parse first argument as conditional expression. (c_parser_gnu_attribute, c_parser_std_attribute): Adjust c_parser_attribute_arguments callers. (c_parser_statement_after_labels) <case RID_ATTRIBUTE>: Handle assume attribute. gcc/cp/ * cp-tree.h (process_stmt_assume_attribute): Implement C++23 P1774R8 - Portable assumptions. Declare. (diagnose_failing_condition): Declare. (find_failing_clause): Likewise. * parser.cc (assume_attr): New enumerator. (cp_parser_parenthesized_expression_list): Handle assume_attr. Remove identifier variable, for id_attr push the identifier into expression_list right away instead of inserting it before all the others at the end. (cp_parser_conditional_expression): New function. (cp_parser_constant_expression): Use it. (cp_parser_statement): Handle assume attribute. (cp_parser_expression_statement): Likewise. (cp_parser_gnu_attribute_list): Use assume_attr for assume attribute. (cp_parser_std_attribute): Likewise. Handle standard assume attribute like gnu::assume. * cp-gimplify.cc (process_stmt_assume_attribute): New function. * constexpr.cc: Include fold-const.h. (find_failing_clause_r, find_failing_clause): New functions, moved from semantics.cc with ctx argument added and if non-NULL, call cxx_eval_constant_expression rather than fold_non_dependent_expr. (cxx_eval_internal_function): Handle IFN_ASSUME. (potential_constant_expression_1): Likewise. * pt.cc (tsubst_copy_and_build): Likewise. * semantics.cc (diagnose_failing_condition): New function. (find_failing_clause_r, find_failing_clause): Moved to constexpr.cc. (finish_static_assert): Use it. Add auto_diagnostic_group. gcc/testsuite/ * gcc.dg/attr-assume-1.c: New test. * gcc.dg/attr-assume-2.c: New test. * gcc.dg/attr-assume-3.c: New test. * g++.dg/cpp2a/feat-cxx2a.C: Add colon to C++20 features comment, add C++20 attributes comment and move C++20 new features after the attributes before them. * g++.dg/cpp23/feat-cxx2b.C: Likewise. Test __has_cpp_attribute(assume). * g++.dg/cpp23/attr-assume1.C: New test. * g++.dg/cpp23/attr-assume2.C: New test. * g++.dg/cpp23/attr-assume3.C: New test. * g++.dg/cpp23/attr-assume4.C: New test.
2022-10-03c++: rename IS_SAME_AS trait code to IS_SAMEPatrick Palka1-1/+1
... to match the trait's canonical spelling __is_same instead of its alternative spelling __is_same_as. gcc/c-family/ChangeLog: * c-common.cc (c_common_reswords): Use RID_IS_SAME instead of RID_IS_SAME_AS. gcc/cp/ChangeLog: * constraint.cc (diagnose_trait_expr): Use CPTK_IS_SAME instead of CPTK_IS_SAME_AS. * cp-trait.def (IS_SAME_AS): Rename to ... (IS_SAME): ... this. * pt.cc (alias_ctad_tweaks): Use CPTK_IS_SAME instead of CPTK_IS_SAME_AS. * semantics.cc (trait_expr_value): Likewise. (finish_trait_expr): Likewise.
2022-09-29c++: implicit lookup of std::initializer_list [PR102576]Patrick Palka1-2/+3
Here the lookup for the implicit use of std::initializer_list fails because we do it using get_namespace_binding, which isn't import aware. Fix this by using lookup_qualified_name instead. PR c++/102576 gcc/cp/ChangeLog: * pt.cc (listify): Use lookup_qualified_name instead of get_namespace_binding. gcc/testsuite/ChangeLog: * g++.dg/modules/pr102576_a.H: New test. * g++.dg/modules/pr102576_b.C: New test.
2022-09-29c++: introduce TRAIT_TYPE alongside TRAIT_EXPRPatrick Palka1-9/+20
We already have generic support for predicate-like traits that yield a boolean value via TRAIT_EXPR, but we lack the same support for traits that yield a type instead of a value. Such support would streamline implementing efficient builtins for the standard library type traits. To that end this patch implements a generic TRAIT_TYPE type alongside TRAIT_EXPR, and reimplements the existing UNDERLYING_TYPE builtin trait using this new TRAIT_TYPE. gcc/cp/ChangeLog: * cp-objcp-common.cc (cp_common_init_ts): Replace UNDERLYING_TYPE with TRAIT_TYPE. * cp-tree.def (TRAIT_TYPE): Define. (UNDERLYING_TYPE): Remove. * cp-tree.h (TRAIT_TYPE_KIND_RAW): Define. (TRAIT_TYPE_KIND): Define. (TRAIT_TYPE_TYPE1): Define. (TRAIT_TYPE_TYPE2): Define. (WILDCARD_TYPE_P): Return true for TRAIT_TYPE. (finish_trait_type): Declare. * cxx-pretty-print.cc (cxx_pretty_printer::primary_expression): Adjust after renaming pp_cxx_trait_expression. (cxx_pretty_printer::simple_type_specifier) <case TRAIT_TYPE>: New. (cxx_pretty_printer::type_id): Replace UNDERLYING_TYPE with TRAIT_TYPE. (pp_cxx_trait_expression): Rename to ... (pp_cxx_trait): ... this. Handle TRAIT_TYPE as well. Correct pretty printing of the trailing arguments. * cxx-pretty-print.h (pp_cxx_trait_expression): Rename to ... (pp_cxx_trait_type): ... this. * error.cc (dump_type) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (dump_type_prefix): Replace UNDERLYING_WITH with TRAIT_TYPE. (dump_type_suffix): Likewise. * mangle.cc (write_type) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. * module.cc (trees_out::type_node) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (trees_in::tree_node): Likewise. * parser.cc (cp_parser_primary_expression): Adjust after renaming cp_parser_trait_expr. (cp_parser_trait_expr): Rename to ... (cp_parser_trait): ... this. Call finish_trait_type for traits that yield a type. (cp_parser_simple_type_specifier): Adjust after renaming cp_parser_trait_expr. * pt.cc (for_each_template_parm_r) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (tsubst): Likewise. (unify): Replace UNDERLYING_TYPE with TRAIT_TYPE. (dependent_type_p_r): Likewise. * semantics.cc (finish_underlying_type): Don't return UNDERLYING_TYPE anymore when processing_template_decl. (finish_trait_type): Define. * tree.cc (strip_typedefs) <case UNDERLYING_TYPE>: Remove. <case TRAIT_TYPE>: New. (cp_walk_subtrees): Likewise. * typeck.cc (structural_comptypes): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-59.C: Adjust expected error message. * g++.dg/ext/underlying_type7.C: Likewise. * g++.dg/ext/underlying_type13.C: New test. * g++.dg/ext/underlying_type14.C: New test.
2022-09-28c++: Add DECL_NTTP_OBJECT_P lang flagNathan Sidwell1-18/+17
VAR_DECLs for NTTPs need to be handled specially by module streaming, in the same manner to type info decls. This reworks their handling to allow that work to drop in. We use DECL_LANG_FLAG_5 to indicate such decls (I didn't notice template_parm_object_p, which looks at the mangled name -- anyway a bit flag on the node is better, IMHO). We break apart the creation routine, so there's now an entry point the module machinery can use directly. gcc/cp/ * cp-tree.h (DECL_NTTP_OBJECT_P): New. (template_parm_object_p): Delete. (build_template_parm_object): Declare. * cxx-pretty-print.cc (pp_cx_template_argument_list): Use DECL_NTTP_OBJECT_P. * error.cc (dump_simple_decl): Likewise. * mangle.cc (write_template_arg): Likewise. * pt.cc (template_parm_object_p): Delete. (create_template_parm_object): Separated out checking from ... (get_template_parm_object): ... this, new external entry point.
2022-09-27c++: Implement C++23 P2266R1, Simpler implicit move [PR101165]Marek Polacek1-12/+38
This patch implements https://wg21.link/p2266, which, once again, changes the implicit move rules. Here's a brief summary of various changes in this area: r125211: Introduced moving from certain lvalues when returning them r171071: CWG 1148, enable move from value parameter on return r212099: CWG 1579, it's OK to call a converting ctor taking an rvalue r251035: CWG 1579, do maybe-rvalue overload resolution twice r11-2411: Avoid calling const copy ctor on implicit move r11-2412: C++20 implicit move changes, remove the fallback overload resolution, allow move on throw of parameters and implicit move of rvalue references P2266 enables the implicit move even for functions that return references. That is, we will now perform a move in X&& foo (X&& x) { return x; } P2266 also removes the fallback overload resolution, but this was resolved by r11-2412: we only do convert_for_initialization with LOOKUP_PREFER_RVALUE in C++17 and older. P2266 also says that a returned move-eligible id-expression is always an xvalue. This required some further short, but nontrivial changes, especially when it comes to deduction, because we have to pay attention to whether we have auto, auto&& (which is like T&&), or decltype(auto) with (un)parenthesized argument. In C++23, decltype(auto) f(int&& x) { return (x); } auto&& f(int x) { return x; } both should deduce to 'int&&' but decltype(auto) f(int x) { return x; } should deduce to 'int'. A cornucopia of tests attached. I've also verified that we behave like clang++. xvalue_p seemed to be broken: since the introduction of clk_implicit_rval, it cannot use '==' when checking for clk_rvalueref. Since this change breaks code, it's only enabled in C++23. In particular, this code will not compile in C++23: int& g(int&& x) { return x; } because x is now treated as an rvalue, and you can't bind a non-const lvalue reference to an rvalue. This patch also fixes PR106882 (the check_return_expr changes). PR c++/101165 PR c++/106882 gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Define __cpp_implicit_move. gcc/cp/ChangeLog: * call.cc (reference_binding): Check clk_implicit_rval in C++20 only. * cp-tree.h (unparenthesized_id_or_class_member_access_p): Declare. * pt.cc (unparenthesized_id_or_class_member_access_p): New function, broken out of... (do_auto_deduction): ...here. Use it. In C++23, maybe call treat_lvalue_as_rvalue_p. * tree.cc (xvalue_p): Check & clk_rvalueref, not == clk_rvalueref. * typeck.cc (check_return_expr): Allow implicit move for functions returning a reference as well, or when the return value type is not a scalar type. gcc/testsuite/ChangeLog: * g++.dg/conversion/pr41426.C: Add dg-error for C++23. * g++.dg/cpp0x/elision_weak.C: Likewise. * g++.dg/cpp0x/move-return3.C: Only link in c++20_down. * g++.dg/cpp1y/decltype-auto2.C: Add dg-error for C++23. * g++.dg/cpp1y/lambda-generic-89419.C: Likewise. * g++.dg/cpp23/feat-cxx2b.C: Test __cpp_implicit_move. * g++.dg/gomp/pr56217.C: Only compile in c++20_down. * g++.dg/warn/Wno-return-local-addr.C: Add dg-error for C++23. * g++.dg/warn/Wreturn-local-addr.C: Adjust dg-error. * g++.old-deja/g++.brendan/crash55.C: Add dg-error for C++23. * g++.old-deja/g++.jason/temporary2.C: Likewise. * g++.old-deja/g++.mike/p2846b.C: Adjust. * g++.dg/cpp1y/decltype-auto6.C: New test. * g++.dg/cpp23/decltype1.C: New test. * g++.dg/cpp23/decltype2.C: New test. * g++.dg/cpp23/elision1.C: New test. * g++.dg/cpp23/elision2.C: New test. * g++.dg/cpp23/elision3.C: New test. * g++.dg/cpp23/elision4.C: New test. * g++.dg/cpp23/elision5.C: New test. * g++.dg/cpp23/elision6.C: New test. * g++.dg/cpp23/elision7.C: New test.
2022-09-27openmp: Add OpenMP assume, assumes and begin/end assumes supportJakub Jelinek1-0/+1
The following patch implements OpenMP 5.1 #pragma omp assume #pragma omp assumes and #pragma omp begin assumes #pragma omp end assumes directive support for C and C++. Currently it doesn't remember anything from the assumption clauses for later, so is mainly to support the directives and diagnose errors in their use. If the recently posted C++23 [[assume (cond)]]; support makes it in, the intent is that this can be easily adjusted at least for the #pragma omp assume directive with holds clause(s) to use the same infrastructure. Now, C++23 portable assumptions are slightly different from OpenMP 5.1 assumptions' holds clause in that C++23 assumption holds just where it appears, while OpenMP 5.1 assumptions hold everywhere in the scope of the directive. For assumes directive which can appear at file or namespace scope it is the whole TU and everything that functions from there call at runtime, for begin assumes/end assumes pair all the functions in between those directives and everything they call and for assume directive the associated (currently structured) block. I have no idea how to represents such holds to be usable for optimizers, except to make #pragma omp assume holds (cond) block; expand essentially to [[assume (cond)]]; block; or [[assume (cond)]]; block; [[assume (cond)]]; for now. Except for holds clause, the other assumptions are OpenMP related, I'd say we should brainstorm where it would be useful to optimize based on such information (I guess e.g. in target regions it easily could) and only when we come up with something like that think about how to propagate the assumptions to the optimizers. 2022-09-27 Jakub Jelinek <jakub@redhat.com> gcc/c-family/ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_ASSUME, PRAGMA_OMP_ASSUMES and PRAGMA_OMP_BEGIN. Rename PRAGMA_OMP_END_DECLARE_TARGET to PRAGMA_OMP_END. * c-pragma.cc (omp_pragmas): Add assumes and begin. For end rename PRAGMA_OMP_END_DECLARE_TARGET to PRAGMA_OMP_END. (omp_pragmas_simd): Add assume. * c-common.h (c_omp_directives): Declare. * c-omp.cc (omp_directives): Rename to ... (c_omp_directives): ... this. No longer static. Uncomment assume, assumes, begin assumes and end assumes entries. In end declare target entry rename PRAGMA_OMP_END_DECLARE_TARGET to PRAGMA_OMP_END. (c_omp_categorize_directive): Adjust for omp_directives to c_omp_directives renaming. gcc/c/ * c-lang.h (current_omp_begin_assumes): Declare. * c-parser.cc: Include bitmap.h. (c_parser_omp_end_declare_target): Rename to ... (c_parser_omp_end): ... this. Handle also end assumes. (c_parser_omp_begin, c_parser_omp_assumption_clauses, c_parser_omp_assumes, c_parser_omp_assume): New functions. (c_parser_translation_unit): Also diagnose #pragma omp begin assumes without corresponding #pragma omp end assumes. (c_parser_pragma): Use %s in may only be used at file scope diagnostics to decrease number of translatable messages. Handle PRAGMA_OMP_BEGIN and PRAGMA_OMP_ASSUMES. Handle PRAGMA_OMP_END rather than PRAGMA_OMP_END_DECLARE_TARGET and call c_parser_omp_end for it rather than c_parser_omp_end_declare_target. (c_parser_omp_construct): Handle PRAGMA_OMP_ASSUME. * c-decl.cc (current_omp_begin_assumes): Define. gcc/cp/ * cp-tree.h (struct omp_begin_assumes_data): New type. (struct saved_scope): Add omp_begin_assumes member. * parser.cc: Include bitmap.h. (cp_parser_omp_assumption_clauses, cp_parser_omp_assume, cp_parser_omp_assumes, cp_parser_omp_begin): New functions. (cp_parser_omp_end_declare_target): Rename to ... (cp_parser_omp_end): ... this. Handle also end assumes. (cp_parser_omp_construct): Handle PRAGMA_OMP_ASSUME. (cp_parser_pragma): Handle PRAGMA_OMP_ASSUME, PRAGMA_OMP_ASSUMES and PRAGMA_OMP_BEGIN. Handle PRAGMA_OMP_END rather than PRAGMA_OMP_END_DECLARE_TARGET and call cp_parser_omp_end for it rather than cp_parser_omp_end_declare_target. * pt.cc (apply_late_template_attributes): Also temporarily clear omp_begin_assumes. * semantics.cc (finish_translation_unit): Also diagnose #pragma omp begin assumes without corresponding #pragma omp end assumes. gcc/testsuite/ * c-c++-common/gomp/assume-1.c: New test. * c-c++-common/gomp/assume-2.c: New test. * c-c++-common/gomp/assume-3.c: New test. * c-c++-common/gomp/assumes-1.c: New test. * c-c++-common/gomp/assumes-2.c: New test. * c-c++-common/gomp/assumes-3.c: New test. * c-c++-common/gomp/assumes-4.c: New test. * c-c++-common/gomp/begin-assumes-1.c: New test. * c-c++-common/gomp/begin-assumes-2.c: New test. * c-c++-common/gomp/begin-assumes-3.c: New test. * c-c++-common/gomp/begin-assumes-4.c: New test. * c-c++-common/gomp/declare-target-6.c: New test. * g++.dg/gomp/attrs-1.C (bar): Add n1 and n2 arguments, add tests for assume directive. * g++.dg/gomp/attrs-2.C (bar): Likewise. * g++.dg/gomp/attrs-9.C: Add n1 and n2 variables, add tests for begin assumes directive. * g++.dg/gomp/attrs-15.C: New test. * g++.dg/gomp/attrs-16.C: New test. * g++.dg/gomp/attrs-17.C: New test.
2022-09-26c++ modules: variable template partial spec fixes [PR107033]Patrick Palka1-1/+1
In r13-2775-g32d8123cd6ce87 I missed that we need to adjust the call to add_mergeable_specialization in the MK_partial case to correctly handle variable template partial specializations (it currently assumes we're always dealing with one for a class template). This fixes an ICE when converting the testcase from that commit to use an importable header instead of a named module. PR c++/107033 gcc/cp/ChangeLog: * module.cc (trees_in::decl_value): In the MK_partial case for a variable template partial specialization, pass decl_p=true to add_mergeable_specialization, and set spec to the VAR_DECL not the TEMPLATE_DECL. * pt.cc (add_mergeable_specialization): For a variable template partial specialization, set the TREE_TYPE of the new DECL_TEMPLATE_SPECIALIZATIONS node to the TREE_TYPE of the VAR_DECL not the VAR_DECL itself. gcc/testsuite/ChangeLog: * g++.dg/modules/partial-2.cc, g++.dg/modules/partial-2.h: New files, factored out from ... * g++.dg/modules/partial-2_a.C, g++.dg/modules/partial-2_b.C: ... these. * g++.dg/modules/partial-2_c.H: New test. * g++.dg/modules/partial-2_d.C: New test.
2022-09-13c++: two-parameter version of cxx_constant_valuePatrick Palka1-2/+2
Since some callers need the complain parameter but not the object parameter, let's introduce and use an overload of cxx_constant_value that omits the latter. gcc/cp/ChangeLog: * cp-tree.h (cxx_constant_value): Define two-parameter version that omits the object parameter. * decl.cc (build_explicit_specifier): Omit NULL_TREE object argument to cxx_constant_value. * except.cc (build_noexcept_spec): Likewise. * pt.cc (expand_integer_pack): Likewise. (fold_targs_r): Likewise. * semantics.cc (finish_if_stmt_cond): Likewise.
2022-09-13c++: some missing-SFINAE fixesPatrick Palka1-1/+3
It looks like we aren't respecting SFINAE for: * an invalid/non-constant conditional explicit-specifier * a non-constant conditional noexcept-specifier * a non-constant argument to __integer_pack This patch fixes these in the usual way, by passing complain and propagating error_mark_node appropriately. gcc/cp/ChangeLog: * decl.cc (build_explicit_specifier): Pass complain to cxx_constant_value. * except.cc (build_noexcept_spec): Likewise. * pt.cc (expand_integer_pack): Likewise. (tsubst_function_decl): Propagate error_mark_node returned from build_explicit_specifier. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/noexcept-type26.C: New test. * g++.dg/cpp2a/explicit19.C: New test. * g++.dg/ext/integer-pack6.C: New test.
2022-09-12c++: remove '_sfinae' suffix from functionsPatrick Palka1-11/+6
The functions abstract_virtuals_error cxx_constant_value get_target_expr instantiate_non_dependent_expr require_complete_type are each just a non-SFINAE-enabled wrapper for the corresponding SFINAE-enabled version that's suffixed by '_sfinae'. But this suffix is at best redundant since a 'complain' parameter already broadly conveys that a function is SFINAE-enabled, and having two such versions of a function is less concise than just using a default argument for 'complain' (and arguably no less mistake prone). So this patch squashes the two versions of each of the above functions by adding a default 'complain' argument to the SFINAE-enabled version whose '_sfinae' suffix we then remove. gcc/cp/ChangeLog: * call.cc (build_conditional_expr): Adjust calls to '_sfinae'-suffixed functions. (build_temp): Likewise. (convert_like_internal): Likewise. (convert_arg_to_ellipsis): Likewise. (build_over_call): Likewise. (build_cxx_call): Likewise. (build_new_method_call): Likewise. * constexpr.cc (cxx_eval_outermost_constant_expr): Likewise. (cxx_constant_value_sfinae): Rename to ... (cxx_constant_value): ... this. Document its default arguments. (fold_non_dependent_expr): Adjust function comment. * cp-tree.h (instantiate_non_dependent_expr_sfinae): Rename to ... (instantiate_non_dependent_expr): ... this. Give its 'complain' parameter a default argument. (get_target_expr_sfinae, get_target_expr): Likewise. (require_complete_type_sfinae, require_complete_type): Likewise. (abstract_virtuals_error_sfinae, abstract_virtuals_error): Likewise. (cxx_constant_value_sfinae, cxx_constant_value): Likewise. * cvt.cc (build_up_reference): Adjust calls to '_sfinae'-suffixed functions. (ocp_convert): Likewise. * decl.cc (build_explicit_specifier): Likewise. * except.cc (build_noexcept_spec): Likewise. * init.cc (build_new_1): Likewise. * pt.cc (expand_integer_pack): Likewise. (instantiate_non_dependent_expr_internal): Adjust function comment. (instantiate_non_dependent_expr): Rename to ... (instantiate_non_dependent_expr_sfinae): ... this. Document its default argument. (tsubst_init): Adjust calls to '_sfinae'-suffixed functions. (fold_targs_r): Likewise. * semantics.cc (finish_compound_literal): Likewise. (finish_decltype_type): Likewise. (cp_build_bit_cast): Likewise. * tree.cc (build_cplus_new): Likewise. (get_target_expr): Rename to ... (get_target_expr_sfinae): ... this. Document its default argument. * typeck.cc (require_complete_type): Rename to ... (require_complete_type_sfinae): ... this. Document its default argument. (cp_build_array_ref): Adjust calls to '_sfinae'-suffixed functions. (convert_arguments): Likewise. (cp_build_binary_op): Likewise. (build_static_cast_1): Likewise. (cp_build_modify_expr): Likewise. (convert_for_initialization): Likewise. * typeck2.cc (abstract_virtuals_error): Rename to ... (abstract_virtuals_error_sfinae): ... this. Document its default argument. (build_functional_cast_1): Adjust calls to '_sfinae'-suffixed functions.
2022-09-12c++: template-id arguments are evaluated [PR101906]Patrick Palka1-3/+3
Here we're neglecting to clear cp_unevaluated_operand when substituting into the arguments of the alias template-id 'skip<(T(), 0), T>' with T=A, which means cp_unevaluated_operand remains set during mark_used for A::A() and so we don't synthesize it. Later constant evaluation for the substituted template argument '(A(), 0)' (from coerce_template_parms) fails with "'constexpr A::A()' used before its definition" since it was never synthesized. This doesn't happen with a class template because tsubst_aggr_type clears cp_unevaluated_operand during substitution thereof. But since template arguments are generally manifestly constant-evaluated, which in turn are evaluated even in an unevaluated operand, we should be clearing cp_unevaluated_operand more broadly whenever substituting into any set of template arguments. To that end this patch makes us clear it during tsubst_template_args. PR c++/101906 gcc/cp/ChangeLog: * pt.cc (tsubst_template_args): Set cp_evaluated here. (tsubst_aggr_type): Not here. gcc/testsuite/ChangeLog: * g++.dg/template/evaluated1.C: New test. * g++.dg/template/evaluated1a.C: New test. * g++.dg/template/evaluated1b.C: New test. * g++.dg/template/evaluated1c.C: New test.
2022-09-12c++: cast to array of unknown bound [PR93259]Jason Merrill1-3/+3
We already know to treat a variable of array-of-unknown-bound type as dependent, we should do the same for arr{}. PR c++/93259 gcc/cp/ChangeLog: * pt.cc (type_dependent_expression_p): Treat a compound literal of array-of-unknown-bound type like a variable. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array17.C: New test.
2022-09-12c++: Refer to internal linkage for -Wsubobject-linkage [PR86491]Jonathan Wakely1-1/+1
Since C++11 relaxed the requirement for template arguments to have external linkage, it's possible to get -Wsubobject-linkage warnings without using any anonymous namespaces. This confuses users when they get diagnostics that refer to an anonymous namespace that doesn't exist in their code. This changes the diagnostic to say "has internal linkage" for C++11 and later, if the type isn't actually a member of the anonymous namespace. Making that distinction involved renaming the current decl_anon_ns_mem_p to something that better expresses its semantics. For C++98 template arguments declared with 'static' are ill-formed anyway, so the only way this warning can arise is via anonymous namespaces. That means the existing wording is accurate for C++98 and so we can keep it. PR c++/86491 gcc/cp/ChangeLog: * decl2.cc (constrain_class_visibility): Adjust wording of -Wsubobject-linkage for cases where anonymous namespaces aren't used. * tree.cc (decl_anon_ns_mem_p): Now only true for actual anonymous namespace members, rename old semantics to... (decl_internal_context_p): ...this. * cp-tree.h, name-lookup.cc, pt.cc: Adjust. gcc/testsuite/ChangeLog: * g++.dg/warn/anonymous-namespace-3.C: Use separate dg-warning directives for C++98 and everything else. * g++.dg/warn/Wsubobject-linkage-5.C: New test.
2022-09-06openmp: Introduce gimple_omp_ordered_standalone_pJakub Jelinek1-3/+8
On Sat, Sep 03, 2022 at 10:07:27AM +0200, Jakub Jelinek via Gcc-patches wrote: > Incrementally, I'd like to change the way we differentiate between > stand-alone and block-associated ordered constructs, because the current > way of looking for presence of doacross clause doesn't work well if those > clauses are removed because they had been invalid (wrong syntax or > unknown variables in it etc.) The following, so far only lightly tested, patch implements that. 2022-09-06 Jakub Jelinek <jakub@redhat.com> gcc/ * gimple.h (enum gf_mask): Add GF_OMP_ORDERED_STANDALONE enumerator. (gimple_omp_subcode): Use GIMPLE_OMP_ORDERED instead of GIMPLE_OMP_TEAMS as upper bound. (gimple_omp_ordered_standalone_p, gimple_omp_ordered_standalone): New inline functions. * gimplify.cc (find_standalone_omp_ordered): Look for OMP_ORDERED with NULL OMP_ORDERED_BODY rather than with OMP_DOACROSS clause. (gimplify_expr): Call gimple_omp_ordered_standalone for OMP_ORDERED with NULL OMP_ORDERED_BODY. * omp-low.cc (check_omp_nesting_restrictions): Use gimple_omp_ordered_standalone_p test instead of omp_find_clause (..., OMP_CLAUSE_DOACROSS). (lower_omp_ordered): Likewise. * omp-expand.cc (expand_omp, build_omp_regions_1, omp_make_gimple_edges): Likewise. gcc/cp/ * pt.cc (tsubst_expr) <case OMP_ORDERED>: If OMP_BODY was NULL, keep it NULL after instantiation too. gcc/testsuite/ * c-c++-common/gomp/sink-3.c: Don't expect a superfluous error during error recovery. * c-c++-common/gomp/doacross-6.c (foo): Add further tests.
2022-09-03openmp: Partial OpenMP 5.2 doacross and omp_cur_iteration supportJakub Jelinek1-6/+7
The following patch implements part of the OpenMP 5.2 changes related to ordered loops and with the assumed resolution of https://github.com/OpenMP/spec/issues/3302 issues. The changes are: 1) the depend clause on stand-alone ordered constructs has been renamed to doacross (because depend clause has different syntax on other constructs) with some syntax changes below, depend clause is deprecated (we'll deprecate stuff on the GCC side only when we have everything else from 5.2 implemented) depend(source) -> doacross(source:) or doacross(source:omp_cur_iteration) depend(sink:vec) -> doacross(sink:vec) (where vec has the same syntax as before) 2) in 5.1 and before it has been significant whether ordered clause has or doesn't have an argument, if it didn't, only block-associated ordered could appear in the body, if it did, only stand-alone ordered could appear in the body, all loops had to be perfectly nested, no associated range-based for loops, no linear clause on work-sharing loop and ordered clause with an argument wasn't allowed on composite for simd. In 5.2, whether ordered clause has or doesn't have an argument is insignificant (except for bugs in the standard, #3302 mentions those), if the argument is missing, it is simply treated as equal to collapse argument (if any, otherwise 1). The implementation better should be able to differentiate between ordered and doacross loops at compile time which previously was through the absence or presence of the argument, now it is done through looking at the body of the construct lexically and looking for stand-alone ordered constructs. If there are any, it is to be handled as doacross loop, otherwise it is ordered loop (but in that case ordered argument if present must be equal to collapse argument - 5.2 says instead it must be one, but that is clearly wrong and mentioned in #3302) - stand-alone ordered constructs must appear lexically in the body (and had to before as well). For the restrictions mentioned above, the for simd restriction is gone (stand-alone ordered can't appear in simd construct, so that is enough), and the other rules are expected to be changed into something related to presence of stand-alone ordered constructs in the body 3) 5.2 allows a new syntax, doacross(sink:omp_cur_iteration-1), which means wait for previous iteration in the iteration space of all the associated loops The following patch implements that, except that we sorry for now on the doacross(sink:omp_cur_iteration-1) syntax during omp expansion because library side isn't done yet for it. It doesn't implement it for the Fortran FE either. Incrementally, I'd like to change the way we differentiate between stand-alone and block-associated ordered constructs, because the current way of looking for presence of doacross clause doesn't work well if those clauses are removed because they had been invalid (wrong syntax or unknown variables in it etc.) and of course implement doacross(sink:omp_cur_iteration-1). 2022-09-03 Jakub Jelinek <jakub@redhat.com> gcc/ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DOACROSS. (enum omp_clause_depend_kind): Remove OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK, add OMP_CLAUSE_DEPEND_INVALID. (enum omp_clause_doacross_kind): New type. (struct tree_omp_clause): Add subcode.doacross_kind member. * tree.h (OMP_CLAUSE_DEPEND_SINK_NEGATIVE): Remove. (OMP_CLAUSE_DOACROSS_KIND): Define. (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE): Define. (OMP_CLAUSE_DOACROSS_DEPEND): Define. (OMP_CLAUSE_ORDERED_DOACROSS): Define. * tree.cc (omp_clause_num_ops, omp_clause_code_name): Add OMP_CLAUSE_DOACROSS entries. * tree-nested.cc (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Handle OMP_CLAUSE_DOACROSS. * tree-pretty-print.cc (dump_omp_clause): Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. Handle OMP_CLAUSE_DOACROSS. * gimplify.cc (gimplify_omp_depend): Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. (gimplify_scan_omp_clauses): Likewise. Handle OMP_CLAUSE_DOACROSS. (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_DOACROSS. (find_standalone_omp_ordered): New function. (gimplify_omp_for): When OMP_CLAUSE_ORDERED is present, search body for OMP_ORDERED with OMP_CLAUSE_DOACROSS and if found, set OMP_CLAUSE_ORDERED_DOACROSS. (gimplify_omp_ordered): Don't handle OMP_CLAUSE_DEPEND_SINK or OMP_CLAUSE_DEPEND_SOURCE, instead check OMP_CLAUSE_DOACROSS, adjust diagnostics that presence or absence of ordered clause parameter is irrelevant. Handle doacross(sink:omp_cur_iteration-1). Use actual user name of the clause - doacross or depend - in diagnostics. * omp-general.cc (omp_extract_for_data): Don't set fd->ordered if !OMP_CLAUSE_ORDERED_DOACROSS (t). If OMP_CLAUSE_ORDERED_DOACROSS (t) but !OMP_CLAUSE_ORDERED_EXPR (t), set fd->ordered to -1 and set it after the loop in that case to fd->collapse. * omp-low.cc (check_omp_nesting_restrictions): Don't handle OMP_CLAUSE_DEPEND_SOURCE nor OMP_CLAUSE_DEPEND_SINK, instead check OMP_CLAUSE_DOACROSS. Use actual user name of the clause - doacross or depend - in diagnostics. Diagnose mixing of stand-alone and block associated ordered constructs binding to the same loop. (lower_omp_ordered_clauses): Don't handle OMP_CLAUSE_DEPEND_SINK, instead handle OMP_CLAUSE_DOACROSS. (lower_omp_ordered): Look for OMP_CLAUSE_DOACROSS instead of OMP_CLAUSE_DEPEND. (lower_depend_clauses): Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. * omp-expand.cc (expand_omp_ordered_sink): Emit a sorry for doacross(sink:omp_cur_iteration-1). (expand_omp_ordered_source_sink): Use OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of OMP_CLAUSE_DEPEND_SINK_NEGATIVE. Use actual user name of the clause - doacross or depend - in diagnostics. (expand_omp): Look for OMP_CLAUSE_DOACROSS clause instead of OMP_CLAUSE_DEPEND. (build_omp_regions_1): Likewise. (omp_make_gimple_edges): Likewise. * lto-streamer-out.cc (hash_tree): Handle OMP_CLAUSE_DOACROSS. * tree-streamer-in.cc (unpack_ts_omp_clause_value_fields): Likewise. * tree-streamer-out.cc (pack_ts_omp_clause_value_fields): Likewise. gcc/c-family/ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DOACROSS. * c-omp.cc (c_finish_omp_depobj): Check also for OMP_CLAUSE_DOACROSS clause and diagnose it. Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. Assert kind is not OMP_CLAUSE_DEPEND_INVALID. gcc/c/ * c-parser.cc (c_parser_omp_clause_name): Handle doacross. (c_parser_omp_clause_depend_sink): Renamed to ... (c_parser_omp_clause_doacross_sink): ... this. Add depend_p argument. Handle parsing of doacross(sink:omp_cur_iteration-1). Use OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it. (c_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source) and set OMP_CLAUSE_DOACROSS_DEPEND on it. (c_parser_omp_clause_doacross): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS. (c_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of OMP_CLAUSE_DEPEND_SOURCE. (c_parser_omp_for_loop): Don't diagnose here linear clause together with ordered with argument. (c_parser_omp_simd): Don't diagnose ordered clause with argument on for simd. (OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS. (c_parser_omp_ordered): Handle also doacross and adjust for it diagnostic wording. * c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS. Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. gcc/cp/ * parser.cc (cp_parser_omp_clause_name): Handle doacross. (cp_parser_omp_clause_depend_sink): Renamed to ... (cp_parser_omp_clause_doacross_sink): ... this. Add depend_p argument. Handle parsing of doacross(sink:omp_cur_iteration-1). Use OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it. (cp_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source) and set OMP_CLAUSE_DOACROSS_DEPEND on it. (cp_parser_omp_clause_doacross): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS. (cp_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of OMP_CLAUSE_DEPEND_SOURCE. (cp_parser_omp_for_loop): Don't diagnose here linear clause together with ordered with argument. (cp_parser_omp_simd): Don't diagnose ordered clause with argument on for simd. (OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS. (cp_parser_omp_ordered): Handle also doacross and adjust for it diagnostic wording. * pt.cc (tsubst_omp_clause_decl): Use OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of OMP_CLAUSE_DEPEND_SINK_NEGATIVE. (tsubst_omp_clauses): Handle OMP_CLAUSE_DOACROSS. (tsubst_expr): Use OMP_CLAUSE_DEPEND_INVALID instead of OMP_CLAUSE_DEPEND_SOURCE. * semantics.cc (cp_finish_omp_clause_depend_sink): Rename to ... (cp_finish_omp_clause_doacross_sink): ... this. (finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS. Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. gcc/fortran/ * trans-openmp.cc (gfc_trans_omp_clauses): Use OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS clause instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND on it. gcc/testsuite/ * c-c++-common/gomp/doacross-2.c: Adjust expected diagnostics. * c-c++-common/gomp/doacross-5.c: New test. * c-c++-common/gomp/doacross-6.c: New test. * c-c++-common/gomp/nesting-2.c: Adjust expected diagnostics. * c-c++-common/gomp/ordered-3.c: Likewise. * c-c++-common/gomp/sink-3.c: Likewise. * gfortran.dg/gomp/nesting-2.f90: Likewise.
2022-08-17c++: Tweak for -Wpessimizing-move in templates [PR89780]Marek Polacek1-0/+3
In my previous patches I've been extending our std::move warnings, but this tweak actually dials it down a little bit. As reported in bug 89780, it's questionable to warn about expressions in templates that were type-dependent, but aren't anymore because we're instantiating the template. As in, template <typename T> Dest withMove() { T x; return std::move(x); } template Dest withMove<Dest>(); // #1 template Dest withMove<Source>(); // #2 Saying that the std::move is pessimizing for #1 is not incorrect, but it's not useful, because removing the std::move would then pessimize #2. So the user can't really win. At the same time, disabling the warning just because we're in a template would be going too far, I still want to warn for template <typename> Dest withMove() { Dest x; return std::move(x); } because the std::move therein will be pessimizing for any instantiation. So I'm using the suppress_warning machinery to that effect. Problem: I had to add a new group to nowarn_spec_t, otherwise suppressing the -Wpessimizing-move warning would disable a whole bunch of other warnings, which we really don't want. PR c++/89780 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build) <case CALL_EXPR>: Maybe suppress -Wpessimizing-move. * typeck.cc (maybe_warn_pessimizing_move): Don't issue warnings if they are suppressed. (check_return_expr): Disable -Wpessimizing-move when returning a dependent expression. gcc/ChangeLog: * diagnostic-spec.cc (nowarn_spec_t::nowarn_spec_t): Handle OPT_Wpessimizing_move and OPT_Wredundant_move. * diagnostic-spec.h (nowarn_spec_t): Add NW_REDUNDANT enumerator. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/Wpessimizing-move3.C: Remove dg-warning. * g++.dg/cpp0x/Wredundant-move2.C: Likewise.
2022-07-26c++: ICE with erroneous template redeclaration [PR106311]Marek Polacek1-1/+4
Here we ICE trying to get DECL_SOURCE_LOCATION of the parm that happens to be error_mark_node in this ill-formed test. I kept running into this while reducing code, so it'd be good to have it fixed. PR c++/106311 gcc/cp/ChangeLog: * pt.cc (redeclare_class_template): Check DECL_P before accessing DECL_SOURCE_LOCATION. gcc/testsuite/ChangeLog: * g++.dg/template/redecl5.C: New test.
2022-07-22c++: CTAD from initializer list [PR106366]Patrick Palka1-16/+15
During CTAD, we currently perform the first phase of overload resolution from [over.match.list] only if the class template has a list constructor. But according to [over.match.class.deduct]/4 it should be enough to just have a guide that looks like a list constructor (which is a more general criterion in light of user-defined guides). PR c++/106366 gcc/cp/ChangeLog: * pt.cc (do_class_deduction): Don't consider TYPE_HAS_LIST_CTOR when setting try_list_ctor. Reset args even when try_list_ctor is true and there are no list candidates. Call resolve_args on the reset args. Rename try_list_ctor to try_list_cand. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/class-deduction112.C: New test.
2022-07-13c++: non-dependent call to consteval operator [PR105912]Patrick Palka1-6/+6
Here we're crashing when substituting a non-dependent call to a consteval operator, whose CALL_EXPR_OPERATOR_SYNTAX flag we try to propagate to the result, but the result isn't a CALL_EXPR since the selected function is consteval. This patch fixes this by checking the result of extract_call_expr accordingly. (Note that we can't check DECL_IMMEDIATE_FUNCTION_P here because we don't know which function was selected by overload resolution from here.) PR c++/105912 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build) <case CALL_EXPR>: Guard against NULL_TREE extract_call_expr result. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval31.C: New test.
2022-07-13c++: dependence of constrained memfn from current inst [PR105842]Patrick Palka1-6/+33
Here we incorrectly deem the calls to func1, func2 and tmpl2 as ambiguous ahead of time ultimately because we mishandle dependence of a constrained member function from the current instantiation. In type_dependent_expression_p, we already consider dependence of a TEMPLATE_DECL's constraints (via uses_outer_template_parms), but neglect to do the same for a FUNCTION_DECL (such as that for func1). And in satisfy_declaration_constraints, we give up if _any_ template argument is dependent, but for non-dependent member functions from the current instantiation (such as func2 and tmpl2), we can and must check constraints as long as the innermost arguments aren't dependent. PR c++/105842 gcc/cp/ChangeLog: * constraint.cc (satisfy_declaration_constraints): Refine early exit test for argument dependence. * cp-tree.h (uses_outer_template_parms_in_constraints): Declare. * pt.cc (template_class_depth): Handle TI_TEMPLATE being a FIELD_DECL. (usse_outer_template_parms): Factor out constraint dependence test into ... (uses_outer_template_parms_in_constraints): ... here. (type_dependent_expression_p): Use it for FUNCTION_DECL. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-memtmpl6.C: New test.
2022-07-07c++: generic targs and identity substitution [PR105956]Patrick Palka1-64/+138
In r13-1045-gcb7fd1ea85feea I assumed that substitution into generic DECL_TI_ARGS corresponds to an identity mapping of the given arguments, and hence its safe to always elide such substitution. But this PR demonstrates that such a substitution isn't always the identity mapping, in particular when there's an ARGUMENT_PACK_SELECT argument, which gets handled specially during substitution: * when substituting an APS into a template parameter, we strip the APS to its underlying argument; * and when substituting an APS into a pack expansion, we strip the APS to its underlying argument pack. In this testcase, when expanding the pack expansion pattern (idx + Ns)... with Ns={0,1}, we specialize idx twice, first with Ns=APS<0,{0,1}> and then Ns=APS<1,{0,1}>. The DECL_TI_ARGS of idx are the generic template arguments of the enclosing class template impl, so before r13-1045, we'd substitute into its DECL_TI_ARGS which gave Ns={0,1} as desired. But after r13-1045, we elide this substitution and end up attempting to hash the original Ns argument, an APS, which ICEs. So this patch reverts that part of r13-1045. I considered using preserve_args in this case instead, but that'd break the static_assert in the testcase because preserve_args always strips APS to its underlying argument, but here we want to strip it to its underlying argument pack, so we'd incorrectly end up forming the specializations impl<0>::idx and impl<1>::idx instead of impl<0,1>::idx. Although we can't elide the substitution into DECL_TI_ARGS in light of ARGUMENT_PACK_SELECT, it should still be safe to elide template argument coercion in the case of a non-template decl, which this patch preserves. It's unfortunate that we need to remove this optimization just because it doesn't hold for one special tree code. So this patch implements a heuristic in tsubst_template_args to avoid allocating a new TREE_VEC if the substituted elements are identical to those of a level from ARGS, as well as a similar heuristic for tsubst_argument_pack. It turns out that about 40% of all calls to tsubst_template_args benefit from this, and it reduces memory usage by about 4% for e.g. range-v3's zip.cpp (relative to r13-1045) which more than makes up for the reversion. PR c++/105956 gcc/cp/ChangeLog: * pt.cc (template_arg_to_parm): Define. (tsubst_argument_pack): Try to reuse the corresponding ARGUMENT_PACK from 'args' when substituting into a generic ARGUMENT_PACK for a variadic template parameter. (tsubst_template_args): Move variable declarations closer to their first use. Replace 'orig_t' with 'r'. Rename 'need_new' to 'const_subst_p'. Heuristically detect if the substituted elements are identical to that of a level from 'args' and avoid allocating a new TREE_VEC if so. Add sanity check for the length of the new TREE_VEC, and remove dead ARGUMENT_PACK_P test. (tsubst_decl) <case TYPE_DECL, case VAR_DECL>: Revert r13-1045-gcb7fd1ea85feea change for avoiding substitution into DECL_TI_ARGS, but still avoid coercion in this case. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/variadic183.C: New test.
2022-06-23c++: context completion in lookup_template_class [PR105982]Patrick Palka1-9/+12
The below testcase demonstrates that completion of the substituted context during lookup_template_class can end up registering the desired specialization for us in more cases than r13-1045-gcb7fd1ea85feea anticipated. In particular this can happen for a non-dependent specialization of a nested class as well. For this testcase, during overload resolution with A's guides, we substitute the deduced argument T=int into the TYPENAME_TYPE B::C, during which we call lookup_template_class for A<T>::B with T=int, which completes A<int> for the first time, which recursively registers the desired specialization of B already. The parent call to lookup_template_class then tries to register the same specialization, triggering an ICE. This patch fixes this by making lookup_template_class determine more directly whether we need to recheck the specializations table after completion of the context -- when and only when the call to complete_type had an effect. PR c++/105982 gcc/cp/ChangeLog: * pt.cc (lookup_template_class): After calling complete_type for the substituted context, check the table again iff the type was previously incomplete and complete_type made it complete. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/class-deduction111.C: New test.
2022-06-23c++: -Waddress and if constexpr [PR94554]Jason Merrill1-11/+32
Like we avoid various warnings for seemingly tautological expressions when substituting a template, we should avoid warning for the implicit conversion to bool in an if statement. I considered also doing this for the conditions in loop expressions, but that seems unnecessary, as a loop condition is unlikely to be a constant. The change to finish_if_stmt_cond isn't necessary since dependent_operand_p looks through IMPLICIT_CONV_EXPR, but makes it more constent with e.g. build_x_binary_op that determines the type of an expression and then builds it using the original operands. PR c++/94554 gcc/cp/ChangeLog: * pt.cc (dependent_operand_p): Split out from... (tsubst_copy_and_build): ...here. (tsubst_expr) [IF_STMT]: Use it. * semantics.cc (finish_if_stmt_cond): Keep the pre-conversion condition in the template tree. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-if38.C: New test.
2022-06-23c++: -Waddress and value-dependent expr [PR105885]Jason Merrill1-0/+1
We already suppress various warnings for code that would be tautological if written directly, but not when it's the result of template substitution. It seems we need to do this for -Waddress as well. PR c++/105885 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build): Also suppress -Waddress for comparison of dependent operands. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/constexpr-if37.C: New test.
2022-06-22c++: tweak deduction with auto template parmsJason Merrill1-0/+2
While looking at PR105964 I noticed that we were unnecessarily repeating the deduction loop because of seeing a non-type parameter with type 'auto'. It is indeed dependent, but not on any other deductions. gcc/cp/ChangeLog: * pt.cc (type_unification_real): An auto tparm can't be affected by other deductions.
2022-06-22c++: dependence of baselink [PR105964]Jason Merrill1-0/+9
helper<token>::c isn't dependent just because we haven't deduced its return type yet. type_dependent_expression_p already knows how to deal with that for bare FUNCTION_DECL, but needs to learn to look through a BASELINK. PR c++/105964 gcc/cp/ChangeLog: * pt.cc (type_dependent_expression_p): Look through BASELINK. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/nontype-auto21.C: New test.
2022-06-10c++: improve TYPENAME_TYPE hashing [PR65328]Patrick Palka1-4/+29
For the testcase in this PR, compilation takes very long ultimately due to our poor hashing of TYPENAME_TYPE causing a huge number of collisions in the spec_hasher and typename_hasher tables. In spec_hasher, we don't hash the components of TYPENAME_TYPE, which means most TYPENAME_TYPE arguments end up contributing the same hash. This is the safe thing to do uniformly since structural_comptypes may try resolving a TYPENAME_TYPE via the current instantiation. But this behavior of structural_comptypes is suppressed from spec_hasher::equal via the comparing_specializations flag, which means spec_hasher::hash can assume it's disabled too. To that end, this patch makes spec_hasher::hash set the flag, and teaches iterative_hash_template_arg to hash the relevant components of TYPENAME_TYPE when the flag is set. And in typename_hasher, the hash function considers TYPE_IDENTIFIER instead of the more informative TYPENAME_TYPE_FULLNAME, which this patch fixes accordingly. After this patch, compile time for the testcase in the PR falls to around 30 seconds on my machine (down from dozens of minutes). PR c++/65328 gcc/cp/ChangeLog: * decl.cc (typename_hasher::hash): Add extra overloads. Use iterative_hash_object instead of htab_hash_pointer. Hash TYPENAME_TYPE_FULLNAME instead of TYPE_IDENTIFIER. (build_typename_type): Use typename_hasher::hash. * pt.cc (spec_hasher::hash): Add two-parameter overload. Set comparing_specializations around the call to hash_tmpl_and_args. (iterative_hash_template_arg) <case TYPENAME_TYPE>: When comparing_specializations, hash the TYPE_CONTEXT and TYPENAME_TYPE_FULLNAME. (tsubst_function_decl): Use spec_hasher::hash instead of hash_tmpl_and_args. (tsubst_template_decl): Likewise. (tsubst_decl): Likewise.
2022-06-10c++: optimize specialization of templated member functionsPatrick Palka1-2/+8
This applies one of the lookup_template_class optimizations from the previous patch to instantiate_template as well. gcc/cp/ChangeLog: * pt.cc (instantiate_template): Don't substitute the context of the most general template if that of the partially instantiated template is already non-dependent.
2022-06-10c++: optimize specialization of nested templated classesPatrick Palka1-28/+50
When substituting a class template specialization, tsubst_aggr_type substitutes the TYPE_CONTEXT before passing it to lookup_template_class. This appears to be unnecessary, however, because the the initial value of lookup_template_class's context parameter is unused outside of the IDENTIFIER_NODE case, and l_t_c performs its own substitution of the context, anyway. So this patch removes the redundant substitution in tsubst_aggr_type. Doing so causes us to ICE on template/nested5.C because during lookup_template_class for A<T>::C::D<S> with T=E and S=S, we substitute and complete the context A<T>::C with T=E, which in turn registers the desired dependent specialization of D for us which we end up trying to register twice. This patch fixes this by checking the specializations table again after completion of the context. This patch also implements a couple of other optimizations: * In lookup_template_class, if the context of the partially instantiated template is already non-dependent, then we could reuse that instead of substituting the context of the most general template. * During tsubst_decl for the TYPE_DECL for an injected-class-name, we can avoid substituting its TREE_TYPE. We can also avoid template argument substitution/coercion for this TYPE_DECL, and for class-scope non-template VAR_/TYPE_DECLs more generally. Together these optimizations improve memory usage for the range-v3 file test/view/zip.cc by about 5%. gcc/cp/ChangeLog: * pt.cc (lookup_template_class): Remove dead stores to context parameter. Don't substitute the context of the most general template if that of the partially instantiated template is already non-dependent. Check the specializations table again after completing the context of a nested dependent specialization. (tsubst_aggr_type) <case RECORD_TYPE>: Don't substitute TYPE_CONTEXT or pass it to lookup_template_class. (tsubst_decl) <case TYPE_DECL, case TYPE_DECL>: Avoid substituting the TREE_TYPE for DECL_SELF_REFERENCE_P. Avoid template argument substitution or coercion in some cases.
2022-06-08c++: non-templated friends [PR105852]Jason Merrill1-4/+10
The previous patch for 105852 avoids copying DECL_TEMPLATE_INFO from a non-templated friend, but it really shouldn't have it in the first place. PR c++/105852 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Change non-templated friend check to an assert. * pt.cc (tsubst_function_decl): Don't set DECL_TEMPLATE_INFO on non-templated friends. (tsubst_friend_function): Adjust.
2022-06-08c++: redeclared hidden friend take 2 [PR105852]Jason Merrill1-1/+28
My previous patch for 105761 avoided copying DECL_TEMPLATE_INFO from a friend to a later definition, but in this testcase we have first a non-friend declaration and then a definition, and we need to avoid copying in that case as well. But we do still want to set new_template_info to avoid GC trouble. With this change, the modules dump correctly identifies ::foo as a non-template function in tpl-friend-2_a.C. Along the way I noticed that the duplicate_decls handling of DECL_UNIQUE_FRIEND_P was backwards for templates, where we don't clobber DECL_LANG_SPECIFIC (olddecl) with DECL_LANG_SPECIFIC (newdecl) like we do for non-templates. PR c++/105852 PR c++/105761 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Avoid copying template info from non-templated friend even if newdecl isn't a definition. Correct handling of DECL_UNIQUE_FRIEND_P on templates. * pt.cc (non_templated_friend_p): New. * cp-tree.h (non_templated_friend_p): Declare it. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-friend-2_a.C: Adjust expected dump. * g++.dg/template/friend74.C: New test.
2022-06-06c++: function NTTP argument considered unused [PR53164, PR105848]Patrick Palka1-4/+16
Here at parse time the template argument f (an OVERLOAD) in A<f> gets resolved ahead of time to the FUNCTION_DECL f<int>, and we defer marking f<int> as used until instantiation (of g) as usual. Later when instantiating g the type A<f> (where f has already been resolved) is non-dependent, so tsubst_aggr_type avoids re-processing its template arguments, and we end up never actually marking f<int> as used (which means we never instantiate it) even though A<f>::h() later calls it, leading to a link error. This patch works around this issue by looking through ADDR_EXPR when calling mark_used on the substituted callee of a CALL_EXPR. PR c++/53164 PR c++/105848 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build) <case CALL_EXPR>: Look through an ADDR_EXPR callee when calling mark_used. gcc/testsuite/ChangeLog: * g++.dg/template/fn-ptr3.C: New test.
2022-06-03c++: don't substitute TEMPLATE_PARM_CONSTRAINTS [PR100374]Patrick Palka1-7/+35
This patch makes us avoid substituting into the TEMPLATE_PARM_CONSTRAINTS of each template parameter except as necessary for declaration matching, like we already do for the other constituent constraints of a declaration. This patch also improves the CA104 implementation of explicit specialization matching of a constrained function template inside a class template, by considering the function's combined constraints instead of just its trailing constraints. This allows us to correctly handle the first three explicit specializations in concepts-spec2.C below, but because we compare the constraints as a whole, it means we incorrectly accept the fourth explicit specialization which writes #3's constraints in a different way. For complete correctness here, determine_specialization should use tsubst_each_template_parm_constraints and template_parameter_heads_equivalent_p. PR c++/100374 gcc/cp/ChangeLog: * pt.cc (determine_specialization): Compare overall constraints not just the trailing constraints. (tsubst_each_template_parm_constraints): Define. (tsubst_friend_function): Use it. (tsubst_friend_class): Use it. (tsubst_template_parm): Don't substitute TEMPLATE_PARM_CONSTRAINTS. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-spec2.C: New test. * g++.dg/cpp2a/concepts-template-parm11.C: New test.
2022-06-03c++: find_template_parameters and PARM_DECLs [PR105797]Patrick Palka1-5/+5
As explained in r11-4959-gde6f64f9556ae3, the atom cache assumes two equivalent expressions (according to cp_tree_equal) must use the same template parameters (according to find_template_parameters). This assumption turned out to not hold for TARGET_EXPR, which was addressed by that commit. But this assumption apparently doesn't hold for PARM_DECL either: find_template_parameters walks its DECL_CONTEXT but cp_tree_equal by default doesn't consider DECL_CONTEXT unless comparing_specializations is set. Thus in the first testcase below, the atomic constraints of #1 and #2 are equivalent according to cp_tree_equal, but according to find_template_parameters the former uses T and the latter uses both T and U (surprisingly). We could fix this assumption violation by setting comparing_specializations in the atom_hasher, which would make cp_tree_equal return false for the two atoms, but that seems overly pessimistic here. Ideally the atoms should continue being considered equivalent and we instead fix find_template_paremeters to return just T for #2's atom. To that end this patch makes for_each_template_parm_r stop walking the DECL_CONTEXT of a PARM_DECL. This should be safe to do because tsubst_copy / tsubst_decl only substitutes the TREE_TYPE of a PARM_DECL and doesn't bother substituting the DECL_CONTEXT, thus the only relevant template parameters are those used in its type. any_template_parm_r is currently responsible for walking its TREE_TYPE, but I suppose it now makes sense for for_each_template_parm_r to do so instead. In passing this patch also makes for_each_template_parm_r stop walking the DECL_CONTEXT of a VAR_/FUNCTION_DECL since doing so after walking DECL_TI_ARGS is redundant, I think. I experimented with not walking DECL_CONTEXT for CONST_DECL, but the second testcase below demonstrates it's necessary to walk it. PR c++/105797 gcc/cp/ChangeLog: * pt.cc (for_each_template_parm_r) <case FUNCTION_DECL, VAR_DECL>: Don't walk DECL_CONTEXT. <case PARM_DECL>: Likewise. Walk TREE_TYPE. <case CONST_DECL>: Simplify. (any_template_parm_r) <case PARM_DECL>: Don't walk TREE_TYPE. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-decltype4.C: New test. * g++.dg/cpp2a/concepts-memfun3.C: New test.
2022-06-02c++: ICE with template NEW_EXPR [PR105803]Marek Polacek1-0/+8
Here we ICE because value_dependent_expression_p gets a NEW_EXPR whose operand is a type, and we go to the default case which just calls v_d_e_p on each operand of the NEW_EXPR. Since one of them is a type, we crash on the new assert in t_d_e_p. t_d_e_p has code to handle {,VEC_}NEW_EXPR, which at this point was already performed, so I think we can handle these two codes specifically and skip the second operand, which is always going to be a type. PR c++/105803 gcc/cp/ChangeLog: * pt.cc (value_dependent_expression_p): Handle {,VEC_}NEW_EXPR in the switch. gcc/testsuite/ChangeLog: * g++.dg/template/new13.C: New test.
2022-06-01c++: auto function as function argument [PR105779]Jason Merrill1-4/+0
This testcase demonstrates that the issue in PR105623 is not limited to templates, so we should do the marking in a less template-specific place. PR c++/105779 gcc/cp/ChangeLog: * call.cc (resolve_args): Call mark_single_function here. * pt.cc (unify_one_argument): Not here. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/auto-fn63.C: New test.
2022-05-31c++: use auto_timevar instead of timevar_push/popPatrick Palka1-47/+14
r12-5487-g9bf69a8558638c replaced uses of timevar_cond_push/pop with auto_cond_timevar and removed now unnecessary wrapper functions. This patch does the same with timevar_push/pop and auto_timevar. gcc/cp/ChangeLog: * parser.cc: Use auto_timevar instead of timevar_push/pop. Remove wrapper functions. * pt.cc: Likewise.
2022-05-31c++: squash cp_build_qualified_type/_realPatrick Palka1-26/+26
This combines the two differently named versions of the same function into a single function utilizing a default argument. gcc/cp/ChangeLog: * cp-tree.h (cp_build_qualified_type_real): Rename to ... (cp_build_qualified_type): ... this. Give its last parameter a default argument. Remove macro of the same name. * decl.cc (grokdeclarator): Adjust accordingly. * pt.cc (tsubst_aggr_type): Likewise. (rebuild_function_or_method_type): Likewise. (tsubst): Likewise. (maybe_dependent_member_ref): Likewise. (unify): Likewise. * tree.cc (cp_build_qualified_type_real): Rename to ... (cp_build_qualified_type): ... this. Adjust accordingly.
2022-05-31c++: document comp_template_args's default argsPatrick Palka1-13/+11
In passing, use bool for its return type. gcc/cp/ChangeLog: * cp-tree.h (comp_template_args): Change return type to bool. * pt.cc (comp_template_args): Document default arguments. Change return type to bool and adjust returns accordingly.
2022-05-30c++: Add !TYPE_P assert to type_dependent_expression_p [PR99080]Marek Polacek1-0/+2
As discussed here: <https://gcc.gnu.org/pipermail/gcc-patches/2021-February/564629.html>, type_dependent_expression_p should not be called with a type argument. I promised I'd add an assert so here it is. One place needed adjusting. PR c++/99080 gcc/cp/ChangeLog: * pt.cc (type_dependent_expression_p): Assert !TYPE_P. * semantics.cc (finish_id_expression_1): Handle UNBOUND_CLASS_TEMPLATE specifically.
2022-05-27c++: lambda in concept [PR105652]Jason Merrill1-5/+12
We currently check satisfaction in the context of the constrained declaration (which may be wrong, see PR104111). When checking C<int> for S<int>, we currently substitute into the lambda in the context of S<T> (rather than S<int>, which seems wrong if the above isn't wrong), so the new closure type thinks its context is S<T>, which confuses debug output. For the moment, let's work around all of this by overriding the context of the closure. PR c++/105652 gcc/cp/ChangeLog: * pt.cc (tsubst_lambda_expr): Don't let a namespace-scope lambda instantiate into a class-scope lambda. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-lambda20.C: New test.
2022-05-26c++: constrained partial spec forward decl [PR96363]Patrick Palka1-17/+21
Here during cp_parser_single_declaration for #2, we were calling associate_classtype_constraints for TPL<T> (the primary template type) before maybe_process_partial_specialization could get a chance to notice that we're in fact declaring a distinct constrained partial spec and not redeclaring the primary template. This caused us to emit a bogus error about differing constraints b/t the primary template and #2's constraints. This patch fixes this by moving the call to associate_classtype_constraints after the call to shadow_tag (which calls maybe_process_partial_specialization) and adjusting shadow_tag to use the return value of m_p_p_s. Moreover, if we later try to define a constrained partial specialization that's been declared earlier (as in the third testcase), then maybe_new_partial_specialization correctly notices it's a redeclaration and returns NULL_TREE. But in this case we also need to update TYPE to point to the redeclared partial spec (it'll otherwise continue pointing to the primary template type, eventually leading to a bogus error). PR c++/96363 gcc/cp/ChangeLog: * decl.cc (shadow_tag): Use the return value of maybe_process_partial_specialization. * parser.cc (cp_parser_single_declaration): Call shadow_tag before associate_classtype_constraints. * pt.cc (maybe_new_partial_specialization): Change return type to bool. Take 'type' argument by mutable reference. Set 'type' to point to the correct constrained specialization when appropriate. (maybe_process_partial_specialization): Adjust accordingly. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-partial-spec12.C: New test. * g++.dg/cpp2a/concepts-partial-spec12a.C: New test. * g++.dg/cpp2a/concepts-partial-spec13.C: New test.
2022-05-25c++: CTAD with alias and nested template [PR105655]Jason Merrill1-1/+5
Here, alias_ctad_tweaks expect tsubst_decl of a FUNCTION_DECL to return a FUNCTION_DECL. A reasonable expectation, but in this case we were replacing the template args of the class-scope deduction guide with equivalent args, so looking in the hash table we found the partial instantiation stored when instantiating A<int>, which is a TEMPLATE_DECL. It's fine for that to be what is stored, but tsubst_function_decl should never return it. PR c++/105655 gcc/cp/ChangeLog: * pt.cc (build_template_decl): Add assert. (tsubst_function_decl): Don't return a template. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-alias13.C: New test.
2022-05-25c++: deduction from auto fn [PR105623]Jason Merrill1-0/+4
Since my patch for PR90451, we defer mark_used of single functions as late as possible. And since my r12-1273, we keep BASELINK from lookup around rather than reconstruct it later. These both made us try to instantiate g with a function type that still had 'auto' as its return type. PR c++/105623 gcc/cp/ChangeLog: * decl2.cc (mark_used): Copy type from fn to BASELINK. * pt.cc (unify_one_argument): Call mark_single_function. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/auto-fn62.C: New test.
2022-05-24c++: set TYPE_CANONICAL for more template typesPatrick Palka1-46/+55
When forming a class template specialization, lookup_template_class uses structural equality for the specialized type whenever one of its template arguments uses structural equality. This is the sensible thing to do in a vacuum, but given that we already effectively deduplicate class specializations via the type_specializations table, we ought to be able to safely assume that each class specialization is unique and therefore canonical, regardless of the canonicity of the template arguments. To that end this patch makes us use the canonical type machinery for all type specializations, except for the case where a PARM_DECL appears in the template arguments (this special case was recently added by r12-3766-g72394d38d929c7). Additionally, this patch makes us use the canonical type machinery for TEMPLATE_TEMPLATE_PARMs and BOUND_TEMPLATE_TEMPLATE_PARMs, by extending canonical_type_parameter appropriately. A comment in tsubst says it's unsafe to set TYPE_CANONICAL for a lowered TEMPLATE_TEMPLATE_PARM, but I'm not sure this is true anymore. According to Jason, this comment (from r120341) became obsolete when later that year r129844 started to substitute the template parms of ttps. Note that r10-7817-ga6f400239d792d recently changed process_template_parm to clear TYPE_CANONICAL for TEMPLATE_TEMPLATE_PARM consistent with the tsubst comment; this patch changes both functions to set instead of clear TYPE_CANONICAL for ttps. These changes improve compile time of template-heavy code by around 10% for me (with a release compiler). For instance, compile time for the libstdc++ test std/ranges/adaptors/all.cc drops from 1.45s to 1.25s, and for the range-v3 test test/view/zip.cpp from 5.38s to 4.88s. The total number of calls to structural_comptypes for the latter test drops from 10.5M to 1.8M. Memory use is unaffected (as expected). The new testcase verifies we check the r12-3766 PARM_DECL special case in bind_template_template_parm too. gcc/cp/ChangeLog: * cp-tree.h (any_template_arguments_need_structural_equality_p): Declare. * pt.cc (struct ctp_hasher): Define. (ctp_table): Define. (canonical_type_parameter): Use it. (process_template_parm): Set TYPE_CANONICAL for TEMPLATE_TEMPLATE_PARM too. (lookup_template_class_1): Remove now outdated comment for the any_template_arguments_need_structural_equality_p test. (tsubst) <case TEMPLATE_TEMPLATE_PARM, etc>: Don't specifically clear TYPE_CANONICAL for ttps. Set TYPE_CANONICAL on the substituted type later. (any_template_arguments_need_structural_equality_p): Return true for any_targ_node. Don't return true just because a template argument uses structural equality. Add comment for the PARM_DECL special case. (rewrite_template_parm): Set TYPE_CANONICAL on the rewritten parm's type later. * tree.cc (bind_template_template_parm): Set TYPE_CANONICAL when safe to do so. * typeck.cc (structural_comptypes) [check_alias]: Increment processing_template_decl before checking dependent_alias_template_spec_p. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-52830a.C: New test.
2022-05-16OpenMP, C++: Add template support for the has_device_addr clause.Marcel Vollweiler1-0/+2
This patch adds support for list items in the has_device_addr clause which type is given by C++ template parameters. gcc/cp/ChangeLog: * pt.cc (tsubst_omp_clauses): Added OMP_CLAUSE_HAS_DEVICE_ADDR. * semantics.cc (finish_omp_clauses): Added template decl processing. libgomp/ChangeLog: * testsuite/libgomp.c++/target-has-device-addr-7.C: New test. * testsuite/libgomp.c++/target-has-device-addr-8.C: New test. * testsuite/libgomp.c++/target-has-device-addr-9.C: New test.
2022-05-12c++: tighten TMPL_ARGS_LEVEL macroPatrick Palka1-14/+14
This patch makes TMPL_ARGS_LEVEL verify the level argument is valid when the one-dimensional vector case. Doing so uncovered a couple of latent issues: in try_class_unification, we weren't correctly copying targs when it's two-dimensional, and in unify_pack_expansion it seems an inequality test needs to be reversed. This patch fixes both issues, and in passing makes the former function free the temporary copy of targs. gcc/cp/ChangeLog: * cp-tree.h (TMPL_ARGS_LEVEL): Assert LEVEL is 1 when TMPL_ARGS_HAVE_MULTIPLE_LEVELS is false. * pt.cc (try_class_unification): Correctly copy multidimensional targs. Free the copy of targs. (unify_pack_expansion): Fix level comparison.