aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-tree.h
AgeCommit message (Collapse)AuthorFilesLines
2023-10-19c++: indirect change of active union member in constexpr [PR101631,PR102286]Nathaniel Shead1-0/+1
This patch adds checks for attempting to change the active member of a union by methods other than a member access expression. To be able to properly distinguish `*(&u.a) = ` from `u.a = `, this patch redoes the solution for c++/59950 to avoid extranneous *&; it seems that the only case that needed the workaround was when copying empty classes. This patch also ensures that constructors for a union field mark that field as the active member before entering the call itself; this ensures that modifications of the field within the constructor's body don't cause false positives (as these will not appear to be member access expressions). This means that we no longer need to start the lifetime of empty union members after the constructor body completes. As a drive-by fix, this patch also ensures that value-initialised unions are considered to have activated their initial member for the purpose of checking stores and accesses, which catches some additional mistakes pre-C++20. PR c++/101631 PR c++/102286 gcc/cp/ChangeLog: * call.cc (build_over_call): Fold more indirect refs for trivial assignment op. * class.cc (type_has_non_deleted_trivial_default_ctor): Create. * constexpr.cc (cxx_eval_call_expression): Start lifetime of union member before entering constructor. (cxx_eval_component_reference): Check against first member of value-initialised union. (cxx_eval_store_expression): Activate member for value-initialised union. Check for accessing inactive union member indirectly. * cp-tree.h (type_has_non_deleted_trivial_default_ctor): Forward declare. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-89336-3.C: Fix union initialisation. * g++.dg/cpp1y/constexpr-union6.C: New test. * g++.dg/cpp1y/constexpr-union7.C: New test. * g++.dg/cpp2a/constexpr-union2.C: New test. * g++.dg/cpp2a/constexpr-union3.C: New test. * g++.dg/cpp2a/constexpr-union4.C: New test. * g++.dg/cpp2a/constexpr-union5.C: New test. * g++.dg/cpp2a/constexpr-union6.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2023-10-17c++: mangling tweaksJason Merrill1-2/+4
Most of this is introducing the abi_check function to reduce the verbosity of most places that check -fabi-version. The start_mangling change is to avoid needing to zero-initialize additional members of the mangling globals, though I'm not actually adding any. The comment documents existing semantics. gcc/cp/ChangeLog: * mangle.cc (abi_check): New. (write_prefix, write_unqualified_name, write_discriminator) (write_type, write_member_name, write_expression) (write_template_arg, write_template_param): Use it. (start_mangling): Assign from {}. * cp-tree.h: Update comment.
2023-10-16c++: improve fold-expr locationJason Merrill1-3/+3
I want to distinguish between constraint && and fold-expressions there of written by the user and those implied by template parameter type-constraints; to that end, let's improve our EXPR_LOCATION for an explicit fold-expression. The fold3.C change is needed because this moves the caret from the end of the expression to the operator, which means the location of the error refers to the macro invocation rather than the macro definition; both locations are still printed, but which one is an error and which a note changes. gcc/cp/ChangeLog: * parser.cc (cp_parser_fold_expression): Track location range. * semantics.cc (finish_unary_fold_expr) (finish_left_unary_fold_expr, finish_right_unary_fold_expr) (finish_binary_fold_expr): Add location parm. * constraint.cc (finish_shorthand_constraint): Pass it. * pt.cc (convert_generic_types_to_packs): Likewise. * cp-tree.h: Adjust. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic3.C: Add expected column. * g++.dg/cpp1z/fold3.C: Adjust diagnostic lines.
2023-09-20openmp: Add omp::decl attribute support [PR111392]Jakub Jelinek1-0/+1
This patch adds support for (so far C++) omp::decl attribute. For declare simd and declare variant directives it is essentially another spelling of omp::decl, except per discussions it is not allowed inside of omp::sequence attribute. For threadprivate, declare target, allocate and later groupprivate directives it should appertain to variable (or for declare target also function definitions and) declarations and where in normal syntax one specifies a list of variables (or variables and functions), either as argument of the directive or clause argument, such argument is not specified and implied to be the variable it applies to. 2023-09-20 Jakub Jelinek <jakub@redhat.com> PR c++/111392 gcc/ * attribs.cc (decl_attributes): Don't warn on omp::directive attribute on vars or function decls if -fopenmp or -fopenmp-simd. gcc/c-family/ * c-omp.cc (c_omp_directives): Add commented out groupprivate directive entry. gcc/cp/ * parser.h (struct cp_lexer): Add in_omp_decl_attribute member. * cp-tree.h (cp_maybe_parse_omp_decl): Declare. * parser.cc (cp_parser_handle_statement_omp_attributes): Diagnose omp::decl attribute on statements. Adjust diagnostic wording for omp::decl. (cp_parser_omp_directive_args): Add DECL_P argument, set TREE_PUBLIC to it on the DEFERRED_PARSE tree. (cp_parser_omp_sequence_args): Adjust caller. (cp_parser_std_attribute): Handle omp::decl attribute. (cp_parser_omp_var_list): If parser->lexer->in_omp_decl_attribute don't expect any arguments, instead create clause or TREE_LIST for that decl. (cp_parser_late_parsing_omp_declare_simd): Adjust diagnostic wording for omp::decl. (cp_maybe_parse_omp_decl): New function. (cp_parser_omp_declare_target): If parser->lexer->in_omp_decl_attribute and first token isn't name or comma invoke cp_parser_omp_var_list. * decl2.cc (cplus_decl_attributes): Adjust diagnostic wording for omp::decl. Handle omp::decl on declarations. * name-lookup.cc (finish_using_directive): Adjust diagnostic wording for omp::decl. gcc/testsuite/ * g++.dg/gomp/attrs-19.C: New test. * g++.dg/gomp/attrs-20.C: New test. * g++.dg/gomp/attrs-21.C: New test. libgomp/ * libgomp.texi: Mark decl attribute was added to the C++ attribute syntax as implemented.
2023-09-19c++: extend cold, hot attributes to classesJavier Martinez1-0/+1
Most code is cold. This patch extends support for attribute ((cold)) to C++ Classes, Unions, and Structs (RECORD_TYPES and UNION_TYPES) to benefit from encapsulation - reducing the verbosity of using the attribute where deserved. The ((hot)) attribute is also extended for its semantic relation. gcc/c-family/ChangeLog: * c-attribs.cc (handle_hot_attribute): remove warning on RECORD_TYPE and UNION_TYPE when in c_dialect_xx. (handle_cold_attribute): Likewise. gcc/cp/ChangeLog: * class.cc (propagate_class_warmth_attribute): New function. (check_bases_and_members): propagate hot and cold attributes to all FUNCTION_DECL when the record is marked hot or cold. * cp-tree.h (maybe_propagate_warmth_attributes): New function. * decl2.cc (maybe_propagate_warmth_attributes): New function. * method.cc (lazily_declare_fn): propagate hot and cold attributes to lazily declared functions when the record is marked hot or cold. gcc/ChangeLog: * doc/extend.texi: Document attributes hot, cold on C++ types. gcc/testsuite/ChangeLog: * g++.dg/ext/attr-hotness.C: New test. Signed-off-by: Javier Martinez <javier.martinez.bugzilla@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
2023-09-19c++: Move consteval folding to cp_fold_rMarek Polacek1-18/+24
In the review of P2564: <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628747.html> it turned out that in order to correctly handle an example in the paper, we should stop doing immediate evaluation in build_over_call and bot_replace, and instead do it in cp_fold_r. This patch does that. Another benefit is that this is a pretty significant simplification, at least in my opinion. Also, this fixes the c++/110997 ICE (but the test doesn't compile yet). The main drawback seems to be that cp_fold_r doesn't process uninstantiated templates. We still have to handle things like "false ? foo () : 1". To that end, I've added cp_fold_immediate, called on dead branches in cxx_eval_conditional_expression. You'll see that I've reintroduced ADDR_EXPR_DENOTES_CALL_P here. This is to detect *(&foo)) () (s.*&S::foo) () which were deemed ill-formed. gcc/cp/ChangeLog: * call.cc (build_over_call): Set ADDR_EXPR_DENOTES_CALL_P. Don't handle immediate_invocation_p here. * constexpr.cc (cxx_eval_call_expression): Use mce_true for DECL_IMMEDIATE_FUNCTION_P. (cxx_eval_conditional_expression): Call cp_fold_immediate. * cp-gimplify.cc (enum fold_flags): Add ff_fold_immediate. (maybe_replace_decl): Make static. (cp_fold_r): Expand immediate invocations. (cp_fold_immediate_r): New. (cp_fold_immediate): New. * cp-tree.h (ADDR_EXPR_DENOTES_CALL_P): Define. (cp_fold_immediate): Declare. * tree.cc (bot_replace): Don't handle immediate invocations here. libstdc++-v3/ChangeLog: * testsuite/20_util/allocator/105975.cc: Add dg-error. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if2.C: Add xfail. * g++.dg/cpp2a/consteval-memfn1.C: Adjust. * g++.dg/cpp2a/consteval11.C: Remove dg-message. * g++.dg/cpp2a/consteval3.C: Remove dg-message and dg-error. * g++.dg/cpp2a/consteval9.C: Remove dg-message. * g++.dg/cpp2a/consteval32.C: New test. * g++.dg/cpp2a/consteval33.C: New test. * g++.dg/cpp2a/consteval34.C: New test. * g++.dg/cpp2a/consteval35.C: New test.
2023-09-01c++: Fix up mangling of function/block scope static structured bindings ↵Jakub Jelinek1-5/+5
[PR111069] As can be seen on the testcase, we weren't correctly mangling static/thread_local structured bindings (C++20 feature) at function/block scope. The following patch fixes that by using what write_local_name does for those cases (note, structured binding mandling doesn't use the standard path because it needs to pass a list of all the identifiers in the structured binding to the mangling). In addition to that it fixes mangling of various helpers which use write_guarded_name (_ZGV*, _ZTH*, _ZTW*) and kills find_decomp_unqualified_name which for the local names would be too hard to implement and uses write_guarded_name for structured binding related _ZGR* names as well. All the mangled names on the first testcase match now clang++ and my expectations. Because the old mangled names were plain wrong (they mangled the same as structured binding at global scope and resulted in assembly errors if there was more than one static structured binding with the same identifiers in the same (or another) function, I think we don't need to play with another mangling ABI level which turns on/off the old broken way. In addition to that the patch starts to emit abi-tags into the mangle_decomp produced names when needed and emits a -Wabi warning for that as well. To make that work, I had to move cp_maybe_mangle_decomp calls from before cp_finish_decl into a middle of cp_finish_decl after type is deduced and maybe_commonize_var (which also had to be changed not to ignore structured bindings) is called but before anything might need a mangled name for the decl, so a new cp_decomp structure is passed to cp_finish_decl; various other structured binding related functions have been changed to pass pointer to that around instead of passing a tree and unsigned int separately. On decomp9.C, there is a _ZZ3barI1TB3quxEivEDC1o1pEB3qux (g++) vs. _ZZ3barI1TB3quxEivEDC1o1pE (clang++) mangling difference, but that seems to be a clang++ bug and happens also with normal static block vars, doesn't need structured bindings. 2023-09-01 Jakub Jelinek <jakub@redhat.com> PR c++/111069 gcc/ * common.opt (fabi-version=): Document version 19. * doc/invoke.texi (-fabi-version=): Likewise. gcc/c-family/ * c-opts.cc (c_common_post_options): Change latest_abi_version to 19. gcc/cp/ * cp-tree.h (determine_local_discriminator): Add NAME argument with NULL_TREE default. (struct cp_decomp): New type. (cp_finish_decl): Add DECOMP argument defaulted to nullptr. (cp_maybe_mangle_decomp): Remove declaration. (cp_finish_decomp): Add cp_decomp * argument, remove tree and unsigned args. (cp_convert_range_for): Likewise. * decl.cc (determine_local_discriminator): Add NAME argument, use it if non-NULL, otherwise compute it the old way. (maybe_commonize_var): Don't return early for structured bindings. (cp_finish_decl): Add DECOMP argument, if non-NULL, call cp_maybe_mangle_decomp. (cp_maybe_mangle_decomp): Make it static with a forward declaration. Call determine_local_discriminator. Replace FIRST and COUNT arguments with DECOMP argument. (cp_finish_decomp): Replace FIRST and COUNT arguments with DECOMP argument. * mangle.cc (find_decomp_unqualified_name): Remove. (write_unqualified_name): Don't call find_decomp_unqualified_name. (mangle_decomp): Handle mangling of static function/block scope structured bindings. Don't call decl_mangling_context twice. Call check_abi_tags, call write_abi_tags for abi version >= 19 and emit -Wabi warnings if needed. (write_guarded_var_name): Handle structured bindings. (mangle_ref_init_variable): Use write_guarded_var_name. * parser.cc (cp_parser_range_for): Adjust do_range_for_auto_deduction and cp_convert_range_for callers. (do_range_for_auto_deduction): Replace DECOMP_FIRST_NAME and DECOMP_CNT arguments with DECOMP. Adjust cp_finish_decomp caller. (cp_convert_range_for): Replace DECOMP_FIRST_NAME and DECOMP_CNT arguments with DECOMP. Don't call cp_maybe_mangle_decomp, adjust cp_finish_decl and cp_finish_decomp callers. (cp_parser_decomposition_declaration): Don't call cp_maybe_mangle_decomp, adjust cp_finish_decl and cp_finish_decomp callers. (cp_convert_omp_range_for): Adjust do_range_for_auto_deduction and cp_finish_decomp callers. (cp_finish_omp_range_for): Don't call cp_maybe_mangle_decomp, adjust cp_finish_decl and cp_finish_decomp callers. * pt.cc (tsubst_omp_for_iterator): Adjust tsubst_decomp_names caller. (tsubst_decomp_names): Replace FIRST and CNT arguments with DECOMP. (tsubst_expr): Don't call cp_maybe_mangle_decomp, adjust tsubst_decomp_names, cp_finish_decl, cp_finish_decomp and cp_convert_range_for callers. gcc/testsuite/ * g++.dg/cpp2a/decomp8.C: New test. * g++.dg/cpp2a/decomp9.C: New test. * g++.dg/abi/macro0.C: Expect __GXX_ABI_VERSION 1019 rather than 1018.
2023-08-29c++: tweaks for explicit conversion fns diagnosticMarek Polacek1-0/+1
1) When saying that a conversion is erroneous because it would use an explicit constructor, it might be nice to show where exactly the explicit constructor is located. For example, with this patch: [...] explicit.C:4:12: note: 'S::S(int)' declared here 4 | explicit S(int) { } | ^ 2) When a conversion doesn't work out merely because the conversion function necessary to do the conversion couldn't be used because it was marked explicit, it would be useful to the user to say so, rather than just saying "cannot convert". For example, with this patch: explicit.C:13:12: error: cannot convert 'S' to 'bool' in initialization 13 | bool b = S{1}; | ^~~~ | | | S explicit.C:5:12: note: explicit conversion function was not considered 5 | explicit operator bool() const { return true; } | ^~~~~~~~ gcc/cp/ChangeLog: * call.cc (convert_like_internal): Show where the conversion function was declared. (maybe_show_nonconverting_candidate): New. * cp-tree.h (maybe_show_nonconverting_candidate): Declare. * typeck.cc (convert_for_assignment): Call it. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/explicit.C: New test.
2023-08-25OpenMP: C++ support for imperfectly-nested loopsSandra Loosemore1-1/+1
OpenMP 5.0 removed the restriction that multiple collapsed loops must be perfectly nested, allowing "intervening code" (including nested BLOCKs) before or after each nested loop. In GCC this code is moved into the inner loop body by the respective front ends. This patch changes the C++ front end to use recursive descent parsing on nested loops within an "omp for" construct, rather than an iterative approach, in order to preserve proper nesting of compound statements. Preserving cleanups (destructors) for class objects declared in intervening code and loop initializers complicates moving the former into the body of the loop; this is handled by parsing the entire construct before reassembling any of it. gcc/cp/ChangeLog * cp-tree.h (cp_convert_omp_range_for): Adjust declaration. * parser.cc (struct omp_for_parse_data): New. (cp_parser_postfix_expression): Diagnose calls to OpenMP runtime in intervening code. (check_omp_intervening_code): New. (cp_parser_statement_seq_opt): Special-case nested loops, blocks, and other constructs for OpenMP loops. (cp_parser_iteration_statement): Reject loops in intervening code. (cp_parser_omp_for_loop_init): Expand comments and tweak the interface slightly to better distinguish input/output parameters. (cp_convert_omp_range_for): Likewise. (cp_parser_omp_loop_nest): New, split from cp_parser_omp_for_loop and largely rewritten. Add more comments. (insert_structured_blocks): New. (find_structured_blocks): New. (struct sit_data, substitute_in_tree_walker, substitute_in_tree): New. (fixup_blocks_walker): New. (cp_parser_omp_for_loop): Rewrite to use recursive descent instead of a loop. Add logic to reshuffle the bits of code collected during parsing so intervening code gets moved to the loop body. (cp_parser_omp_loop): Remove call to finish_omp_for_block, which is now redundant. (cp_parser_omp_simd): Likewise. (cp_parser_omp_for): Likewise. (cp_parser_omp_distribute): Likewise. (cp_parser_oacc_loop): Likewise. (cp_parser_omp_taskloop): Likewise. (cp_parser_pragma): Reject OpenMP pragmas in intervening code. * parser.h (struct cp_parser): Add omp_for_parse_state field. * pt.cc (tsubst_omp_for_iterator): Adjust call to cp_convert_omp_range_for. * semantics.cc (finish_omp_for): Try harder to preserve location of loop variable init expression for use in diagnostics. (struct fofb_data, finish_omp_for_block_walker): New. (finish_omp_for_block): Allow variables to be bound in a BIND_EXPR nested inside BIND instead of directly in BIND itself. gcc/testsuite/ChangeLog * c-c++-common/goacc/tile-2.c: Adjust expected error patterns. * g++.dg/gomp/attrs-imperfect1.C: New test. * g++.dg/gomp/attrs-imperfect2.C: New test. * g++.dg/gomp/attrs-imperfect3.C: New test. * g++.dg/gomp/attrs-imperfect4.C: New test. * g++.dg/gomp/attrs-imperfect5.C: New test. * g++.dg/gomp/pr41967.C: Adjust expected error patterns. * g++.dg/gomp/tpl-imperfect-gotos.C: New test. * g++.dg/gomp/tpl-imperfect-invalid-scope.C: New test. libgomp/ChangeLog * testsuite/libgomp.c++/attrs-imperfect1.C: New test. * testsuite/libgomp.c++/attrs-imperfect2.C: New test. * testsuite/libgomp.c++/attrs-imperfect3.C: New test. * testsuite/libgomp.c++/attrs-imperfect4.C: New test. * testsuite/libgomp.c++/attrs-imperfect5.C: New test. * testsuite/libgomp.c++/attrs-imperfect6.C: New test. * testsuite/libgomp.c++/imperfect-class-1.C: New test. * testsuite/libgomp.c++/imperfect-class-2.C: New test. * testsuite/libgomp.c++/imperfect-class-3.C: New test. * testsuite/libgomp.c++/imperfect-destructor.C: New test. * testsuite/libgomp.c++/imperfect-template-1.C: New test. * testsuite/libgomp.c++/imperfect-template-2.C: New test. * testsuite/libgomp.c++/imperfect-template-3.C: New test.
2023-08-22c++: maybe_substitute_reqs_for fixJason Merrill1-1/+1
While working on PR109751 I found that maybe_substitute_reqs_for was doing the wrong thing for a non-template friend, substituting in the template args of the scope's original template rather than those of the instantiation. This didn't end up being necessary to fix the PR, but it's still an improvement. gcc/cp/ChangeLog: * pt.cc (outer_template_args): Handle non-template argument. * constraint.cc (maybe_substitute_reqs_for): Pass decl to it. * cp-tree.h (outer_template_args): Adjust.
2023-08-22c++: constrained hidden friends [PR109751]Jason Merrill1-1/+2
r13-4035 avoided a problem with overloading of constrained hidden friends by checking satisfaction, but checking satisfaction early is inconsistent with the usual late checking and can lead to hard errors, so let's not do that after all. We were wrongly treating the different instantiations of the same friend template as the same function because maybe_substitute_reqs_for was failing to actually substitute in the case of a non-template friend. But we don't actually need to do the substitution anyway, because [temp.friend] says that such a friend can't be the same as any other declaration. After fixing that, instead of a redefinition error we got an ambiguous overload error, fixed by allowing constrained hidden friends to coexist until overload resolution, at which point they probably won't be in the same ADL overload set anyway. And we avoid mangling collisions by following the proposed mangling for these friends as a member function with an extra 'F' before the name. I demangle this by just adding [friend] to the name of the function because it's not feasible to reconstruct the actual scope of the function since the mangling ABI doesn't distinguish between class and namespace scopes. PR c++/109751 gcc/cp/ChangeLog: * cp-tree.h (member_like_constrained_friend_p): Declare. * decl.cc (member_like_constrained_friend_p): New. (function_requirements_equivalent_p): Check it. (duplicate_decls): Check it. (grokfndecl): Check friend template constraints. * mangle.cc (decl_mangling_context): Check it. (write_unqualified_name): Check it. * pt.cc (uses_outer_template_parms_in_constraints): Fix for friends. (tsubst_friend_function): Don't check satisfaction. include/ChangeLog: * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_FRIEND. libiberty/ChangeLog: * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_FRIEND. (d_count_templates_scopes): Likewise. (d_print_comp_inner): Likewise. (d_unqualified_name): Handle member-like friend mangling. * testsuite/demangle-expected: Add test. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-friend11.C: Now works. Add template. * g++.dg/cpp2a/concepts-friend15.C: New test.
2023-08-04frontend: Add novector C++ pragmaTamar Christina1-4/+8
FORTRAN currently has a pragma NOVECTOR for indicating that vectorization should not be applied to a particular loop. ICC/ICX also has such a pragma for C and C++ called #pragma novector. As part of this patch series I need a way to easily turn off vectorization of particular loops, particularly for testsuite reasons. This patch proposes a #pragma GCC novector that does the same for C++ as gfortan does for FORTRAN and what ICX/ICX does for C++. I added only some basic tests here, but the next patch in the series uses this in the testsuite in about ~800 tests. gcc/cp/ChangeLog: * cp-tree.h (RANGE_FOR_NOVECTOR): New. (cp_convert_range_for, finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Add novector param. * init.cc (build_vec_init): Default novector to false. * method.cc (build_comparison_op): Likewise. * parser.cc (cp_parser_statement): Likewise. (cp_parser_for, cp_parser_c_for, cp_parser_range_for, cp_convert_range_for, cp_parser_iteration_statement, cp_parser_omp_for_loop, cp_parser_pragma): Support novector. (cp_parser_pragma_novector): New. * pt.cc (tsubst_expr): Likewise. * semantics.cc (finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Likewise. gcc/ChangeLog: * doc/extend.texi: Document it. gcc/testsuite/ChangeLog: * g++.dg/vect/vect.exp (support vect- prefix). * g++.dg/vect/vect-novector-pragma.cc: New test.
2023-07-25c++: Prevent dangling pointers from becoming nullptr in constexpr [PR110619]Nathaniel Shead1-1/+7
Currently, when typeck discovers that a return statement will refer to a local variable it rewrites to return a null pointer. This causes the error messages for using the return value in a constant expression to be unhelpful, especially for reference return values, and is also a visible change to otherwise valid code (as in the linked PR). The transformation is nonetheless important, however, both as a safety guard against attackers being able to gain a handle to other data on the stack, and to prevent duplicate warnings from later null-dereference warning passes. As such, this patch just delays the transformation until cp_genericize, after constexpr function definitions have been generated. PR c++/110619 gcc/cp/ChangeLog: * cp-gimplify.cc (cp_genericize_r): Transform RETURN_EXPRs to not return dangling pointers. * cp-tree.h (RETURN_EXPR_LOCAL_ADDR_P): New flag. (check_return_expr): Add a new parameter. * semantics.cc (finish_return_stmt): Set flag on RETURN_EXPR when referring to dangling pointer. * typeck.cc (check_return_expr): Disable transformation of dangling pointers, instead pass this information to caller. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-110619.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
2023-06-30c++: fix up caching of level lowered ttpsPatrick Palka1-1/+9
Due to level/depth mismatches between the template parameters of a level lowered ttp and the original ttp, the ttp comparison check added by r14-418-g0bc2a1dc327af9 never actually holds outside of erroneous cases. Moreover, it'd be good to also cache the overall TEMPLATE_TEMPLATE_PARM instead of only the TEMPLATE_PARM_INDEX. It's tricky to cache all level lowered ttps since the result of level lowering may depend on more than just the depth of the arguments, e.g. for TT in template<class T> struct A { template<template<T> class TT> void f(); } the substitution T=int yields a different level-lowered ttp than T=char. But these kinds of ttps seem to be rare in practice, and "simple" ttps that don't depend on outer template parameters are easy enough to cache like so. Unfortunately, this means we're back to expecting a duplicate error in nontype12.C again since the ttp in question isn't "simple" so caching of the (erroneous) lowered ttp doesn't happen. gcc/cp/ChangeLog: * cp-tree.h (TEMPLATE_PARM_DESCENDANTS): Harden. (TEMPLATE_TYPE_DESCENDANTS): Define. (TEMPLATE_TEMPLATE_PARM_SIMPLE_P): Define. * pt.cc (reduce_template_parm_level): Revert r14-418-g0bc2a1dc327af9 change. (process_template_parm): Set TEMPLATE_TEMPLATE_PARM_SIMPLE_P appropriately. (uses_outer_template_parms): Determine the outer depth of a template template parm without relying on DECL_CONTEXT. (tsubst) <case TEMPLATE_TEMPLATE_PARM>: Cache lowering a simple template template parm. Consistently use 'code'. gcc/testsuite/ChangeLog: * g++.dg/template/nontype12.C: Refine and XFAIL the dg-bogus duplicate diagnostic check.
2023-06-29c++: cache partial template specialization selectionPatrick Palka1-1/+10
There's currently no cheap way to obtain the partial template specialization (and arguments relative to it) that was selected for a class or variable template specialization. Our only option is to compute the result from scratch via most_specialized_partial_spec. For class templates this isn't really an issue because we usually need this information just once, upon instantiation. But for variable templates we need it upon specialization and also later upon instantiation. We could implement an ad-hoc cache for variable templates only, but it'd be nice for this information to be readily available in general. To that end, this patch adds a TI_PARTIAL_INFO field to TEMPLATE_INFO that holds another TEMPLATE_INFO consisting of the partial template and arguments relative to it, which most_specialized_partial_spec then uses to transparently cache its (now TEMPLATE_INFO) result. Similarly, there's no easy way to go from the DECL_TEMPLATE_RESULT of a partial TEMPLATE_DECL back to that TEMPLATE_DECL. (Our best option is to walk the DECL_TEMPLATE_SPECIALIZATIONS list of the primary TEMPLATE_DECL.) So this patch also uses this new field to link these entities in both directions. gcc/cp/ChangeLog: * cp-tree.h (tree_template_info::partial): New data member. (TI_PARTIAL_INFO): New tree accessor. (most_specialized_partial_spec): Add defaulted bool parameter. * module.cc (trees_out::core_vals) <case TEMPLATE_INFO>: Stream TI_PARTIAL_INFO. (trees_in::core_vals) <case TEMPLATE_INFO>: Likewise. * parser.cc (specialization_of): Adjust after making most_specialized_partial_spec return TEMPLATE_INFO instead of TREE_LIST. * pt.cc (process_partial_specialization): Set TI_PARTIAL_INFO of 'decl' to point back to the partial TEMPLATE_DECL. Likewise (and pass rechecking=true to most_specialization_partial_spec). (instantiate_class_template): Likewise. (instantiate_template): Set TI_PARTIAL_INFO to the result of most_specialization_partial_spec after forming a variable template specialization. (most_specialized_partial_spec): Add 'rechecking' parameter. Exit early if the template is not primary. Use the TI_PARTIAL_INFO of the corresponding TEMPLATE_INFO as a cache unless 'rechecking' is true. Don't bother setting TREE_TYPE of each TREE_LIST. (instantiate_decl): Adjust after making most_specialized_partial_spec return TEMPLATE_INFO instead of TREE_LIST. * ptree.cc (cxx_print_xnode) <case TEMPLATE_INFO>: Dump TI_PARTIAL_INFO.
2023-06-28c++: ahead of time variable template-id coercion [PR89442]Patrick Palka1-1/+1
This patch makes us coerce the arguments of a variable template-id ahead of time, as we do for class template-ids, which causes us to immediately diagnose template parm/arg kind mismatches and arity mismatches. Unfortunately this causes a regression in cpp1z/constexpr-if20.C: coercing the variable template-id m<ar, as> ahead of time means we strip it of typedefs, yielding m<typename C<i>::q, typename C<j>::q>, but in this stripped form we're directly using 'i' and so we expect to have captured it. This is a variable template version of PR107437. PR c++/89442 PR c++/107437 gcc/cp/ChangeLog: * cp-tree.h (lookup_template_variable): Add complain parameter. * parser.cc (cp_parser_template_id): Pass tf_warning_or_error to lookup_template_variable. * pt.cc (lookup_template_variable): Add complain parameter. Coerce template arguments here ... (finish_template_variable): ... instead of here. (lookup_and_finish_template_variable): Check for error_mark_node result from lookup_template_variable. (tsubst_copy) <case TEMPLATE_ID_EXPR>: Pass complain to lookup_template_variable. (instantiate_template): Use build2 instead of lookup_template_variable to build a TEMPLATE_ID_EXPR for most_specialized_partial_spec. gcc/testsuite/ChangeLog: * g++.dg/cpp/pr64127.C: Expect "expected unqualified-id at end of input" error. * g++.dg/cpp0x/alias-decl-ttp1.C: Fix template parameter/argument kind mismatch for variable template has_P_match_V. * g++.dg/cpp1y/pr72759.C: Expect "template argument 1 is invalid" error. * g++.dg/cpp1z/constexpr-if20.C: XFAIL test due to bogus "'i' is not captured" error. * g++.dg/cpp1z/noexcept-type21.C: Fix arity of variable template d. * g++.dg/diagnostic/not-a-function-template-1.C: Add default template argument to variable template A so that A<> is valid. * g++.dg/parse/error56.C: Don't expect "ISO C++ forbids declaration with no type" error. * g++.dg/parse/template30.C: Don't expect "parse error in template argument list" error. * g++.dg/cpp1y/var-templ82.C: New test.
2023-06-28c++: inherited constructor attributesJason Merrill1-0/+1
Inherited constructors are like constructor clones; they don't exist from the language perspective, so they should copy the attributes in the same way. But it doesn't make sense to copy alias or ifunc attributes in either case. Unlike handle_copy_attribute, we do want to copy inlining attributes. The discussion of PR110334 pointed out that we weren't copying the always_inline attribute, leading to poor inlining choices. PR c++/110334 gcc/cp/ChangeLog: * cp-tree.h (clone_attrs): Declare. * method.cc (implicitly_declare_fn): Use it for inherited constructor. * optimize.cc (clone_attrs): New. (maybe_clone_body): Use it. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/nodiscard-inh1.C: New test.
2023-06-07c++: allow NRV and non-NRV returns [PR58487]Jason Merrill1-0/+5
Now that we support NRV from an inner block, we can also support non-NRV returns from other blocks, since once the NRV is out of scope a later return expression can't possibly alias it. This fixes 58487 and half-fixes 53637: now one of the returns is elided, but not the other. Fixing the remaining xfails in these testcases will require a very different approach, probably involving a full tree/block walk from finalize_nrv, and check_return_expr only adding to a list of potential return variables. PR c++/58487 PR c++/53637 gcc/cp/ChangeLog: * cp-tree.h (INIT_EXPR_NRV_P): New. * semantics.cc (finalize_nrv_r): Check it. * name-lookup.h (decl_in_scope_p): Declare. * name-lookup.cc (decl_in_scope_p): New. * typeck.cc (check_return_expr): Allow non-NRV returns if the NRV is no longer in scope. gcc/testsuite/ChangeLog: * g++.dg/opt/nrv26.C: New test. * g++.dg/opt/nrv26a.C: New test. * g++.dg/opt/nrv27.C: New test.
2023-06-06c++: enable NRVO from inner block [PR51571]Jason Merrill1-1/+1
Our implementation of the named return value optimization has been limited to variables declared in the outermost block of the function, to avoid needing to handle the case where the variable needs to be destroyed due to going out of scope. PR92407 pointed out a case we were missing, where the variable goes out of scope due to a goto and we were failing to destroy it. It occurred to me that this problem is the flip side of PR33799, where we need to be sure to destroy the return value if a cleanup throws on return; here we want to avoid destroying the return value when exiting the variable's scope on return. We can use the same flag to indicate to both cleanups that we're returning. This implements the guaranteed copy elision specified by P2025 (which is not yet part of the draft standard). PR c++/51571 PR c++/92407 gcc/cp/ChangeLog: * decl.cc (finish_function): Simplify NRV handling. * except.cc (maybe_set_retval_sentinel): Also set if NRV. (maybe_splice_retval_cleanup): Don't add the cleanup region if we don't need it. * semantics.cc (nrv_data): Add simple field. (finalize_nrv): Set it. (finalize_nrv_r): Check it and retval sentinel. * cp-tree.h (finalize_nrv): Adjust declaration. * typeck.cc (check_return_expr): Remove named_labels check. gcc/testsuite/ChangeLog: * g++.dg/opt/nrv23.C: New test.
2023-06-06c++: fix throwing cleanup with labelJason Merrill1-1/+1
While looking at PR92407 I noticed that the expectations of maybe_splice_retval_cleanup weren't being met; an sk_cleanup level was confusing its attempt to recognize the outer block of the function. And even if I fixed the detection, it failed to actually wrap the body of the function because the STATEMENT_LIST it got only had the label, not anything after it. So I moved the call after poplevel does pop_stmt_list on all the sk_cleanup levels. PR c++/33799 gcc/cp/ChangeLog: * except.cc (maybe_splice_retval_cleanup): Change recognition of function body and try scopes. * semantics.cc (do_poplevel): Call it after poplevel. (at_try_scope): New. * cp-tree.h (maybe_splice_retval_cleanup): Adjust. gcc/testsuite/ChangeLog: * g++.dg/eh/return1.C: Add label cases.
2023-06-03c++: use __cxa_call_terminate for MUST_NOT_THROW [PR97720]Jason Merrill1-0/+2
[except.handle]/7 says that when we enter std::terminate due to a throw, that is considered an active handler. We already implemented that properly for the case of not finding a handler (__cxa_throw calls __cxa_begin_catch before std::terminate) and the case of finding a callsite with no landing pad (the personality function calls __cxa_call_terminate which calls __cxa_begin_catch), but for the case of a throw in a try/catch in a noexcept function, we were emitting a cleanup that calls std::terminate directly without ever calling __cxa_begin_catch to handle the exception. A straightforward way to fix this seems to be calling __cxa_call_terminate instead. However, that requires exporting it from libstdc++, which we have not previously done. Despite the name, it isn't actually part of the ABI standard. Nor is __cxa_call_unexpected, as far as I can tell, but that one is also used by clang. For this case they use __clang_call_terminate; it seems reasonable to me for us to stick with __cxa_call_terminate. I also change __cxa_call_terminate to take void* for simplicity in the front end (and consistency with __cxa_call_unexpected) but that isn't necessary if it's undesirable for some reason. This patch does not fix the issue that representing the noexcept as a cleanup is wrong, and confuses the handler search; since it looks like a cleanup in the EH tables, the unwinder keeps looking until it finds the catch in main(), which it should never have gotten to. Without the try/catch in main, the unwinder would reach the end of the stack and say no handler was found. The noexcept is a handler, and should be treated as one, as it is when the landing pad is omitted. The best fix for that issue seems to me to be to represent an ERT_MUST_NOT_THROW after an ERT_TRY in an action list as though it were an ERT_ALLOWED_EXCEPTIONS (since indeed it is an exception-specification). The actual code generation shouldn't need to change (apart from the change made by this patch), only the action table entry. PR c++/97720 gcc/cp/ChangeLog: * cp-tree.h (enum cp_tree_index): Add CPTI_CALL_TERMINATE_FN. (call_terminate_fn): New macro. * cp-gimplify.cc (gimplify_must_not_throw_expr): Use it. * except.cc (init_exception_processing): Set it. (cp_protect_cleanup_actions): Return it. gcc/ChangeLog: * tree-eh.cc (lower_resx): Pass the exception pointer to the failure_decl. * except.h: Tweak comment. libstdc++-v3/ChangeLog: * libsupc++/eh_call.cc (__cxa_call_terminate): Take void*. * config/abi/pre/gnu.ver: Add it. gcc/testsuite/ChangeLog: * g++.dg/eh/terminate2.C: New test.
2023-06-03c++: replace in_template_functionPatrick Palka1-1/+1
All uses of in_template_function except for the one in cp_make_fname_decl seem like they could be generalized to consider any template context. To that end this patch replaces the predicate with a generalized in_template_context predicate that returns true if we're inside any template context. If we legitimately need to consider only function contexts, as in cp_make_fname_decl, we can just additionally check e.g. current_function_decl. One concrete benefit of this, which the adjusted testcase below demonstrates, is that we no longer instantiate/odr-use entities based on uses within a non-function template. gcc/cp/ChangeLog: * class.cc (build_base_path): Check in_template_context instead of in_template_function. (resolves_to_fixed_type_p): Likewise. * cp-tree.h (in_template_context): Define. (in_template_function): Remove. * decl.cc (cp_make_fname_decl): Check current_function_decl and in_template_context instead of in_template_function. * decl2.cc (mark_used): Check in_template_context instead of in_template_function. * pt.cc (in_template_function): Remove. * semantics.cc (enforce_access): Check in_template_context instead of current_template_parms directly. gcc/testsuite/ChangeLog: * g++.dg/warn/Waddress-of-packed-member2.C: No longer expect a() to be marked as odr-used.
2023-05-18c++: use _P() defines from tree.hBernhard Reutner-Fischer1-2/+2
gcc/cp/ChangeLog: * call.cc (promoted_arithmetic_type_p): Use _P defines from tree.h. (build_conditional_expr): Ditto. (convert_like_internal): Ditto. (convert_arg_to_ellipsis): Ditto. (build_over_call): Ditto. (compare_ics): Ditto. * class.cc (is_empty_base_ref): Ditto. * coroutines.cc (rewrite_param_uses): Ditto. * cp-tree.h (DECL_DISCRIMINATOR_P): Ditto. (ARITHMETIC_TYPE_P): Ditto. * cvt.cc (ocp_convert): Ditto. * cxx-pretty-print.cc (pp_cxx_template_argument_list): Ditto. * decl.cc (layout_var_decl): Ditto. (get_tuple_size): Ditto. * error.cc (dump_simple_decl): Ditto. * lambda.cc (start_lambda_scope): Ditto. * mangle.cc (write_template_arg): Ditto. * method.cc (spaceship_comp_cat): Ditto. * module.cc (node_template_info): Ditto. (trees_out::start): Ditto. (trees_out::decl_node): Ditto. (trees_in::read_var_def): Ditto. (set_instantiating_module): Ditto. * name-lookup.cc (maybe_record_mergeable_decl): Ditto. (consider_decl): Ditto. (maybe_add_fuzzy_decl): Ditto. * pt.cc (convert_nontype_argument): Ditto. * semantics.cc (handle_omp_array_sections_1): Ditto. (finish_omp_clauses): Ditto. (finish_omp_target_clauses_r): Ditto. (is_this_parameter): Ditto. * tree.cc (build_cplus_array_type): Ditto. (is_this_expression): Ditto. * typeck.cc (do_warn_enum_conversions): Ditto. * typeck2.cc (store_init_value): Ditto. (check_narrowing): Ditto.
2023-05-07c++: various code cleanupsPatrick Palka1-3/+3
* Harden some tree accessor macros and fix a couple of bad PLACEHOLDER_TYPE_CONSTRAINTS accesses uncovered by this. * Use strip_innermost_template_args in outer_template_args. * Add !processing_template_decl early exit tests to some dependence predicates. gcc/cp/ChangeLog: * cp-tree.h (PLACEHOLDER_TYPE_CONSTRAINTS_INFO): Harden via TEMPLATE_TYPE_PARM_CHECK. (TPARMS_PRIMARY_TEMPLATE): Harden via TREE_VEC_CHECK. (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Harden via TEMPLATE_TEMPLATE_PARM_CHECK. * cxx-pretty-print.cc (cxx_pretty_printer::simple_type_specifier): Guard PLACEHOLDER_TYPE_CONSTRAINTS access. * error.cc (dump_type) <case TEMPLATE_TYPE_PARM>: Use separate variable to store CLASS_PLACEHOLDER_TEMPLATE result. * pt.cc (outer_template_args): Use strip_innermost_template_args. (any_type_dependent_arguments_p): Exit early if !processing_template_decl. Use range-based for. (any_dependent_template_arguments_p): Likewise.
2023-05-02c++: look for empty base at specific offset [PR109678]Jason Merrill1-1/+2
While looking at the empty base handling for 109678, it occurred to me that we ought to be able to look for an empty base at a specific offset, not just in general. PR c++/109678 gcc/cp/ChangeLog: * cp-tree.h (lookup_base): Add offset parm. * constexpr.cc (cxx_fold_indirect_ref_1): Pass it. * search.cc (struct lookup_base_data_s): Add offset. (dfs_lookup_base): Handle it. (lookup_base): Pass it.
2023-04-24c++, tree: declare some basic functions inlinePatrick Palka1-1/+25
The functions strip_array_types, is_typedef_decl, typedef_variant_p and cp_expr_location are used throughout the C++ front end including in some fairly hot parts (e.g. in the tsubst routines and cp_walk_subtree) and they're small enough that the overhead of calling them out-of-line is relatively significant. So this patch moves their definitions into the appropriate headers to enable inlining them. gcc/cp/ChangeLog: * cp-tree.h (cp_expr_location): Define here. * tree.cc (cp_expr_location): Don't define here. gcc/ChangeLog: * tree.cc (strip_array_types): Don't define here. (is_typedef_decl): Don't define here. (typedef_variant_p): Don't define here. * tree.h (strip_array_types): Define here. (is_typedef_decl): Define here. (typedef_variant_p): Define here.
2023-04-19c++: Define built-in for std::tuple_element [PR100157]Patrick Palka1-1/+1
This adds a new built-in to replace the recursive class template instantiations done by traits such as std::tuple_element and std::variant_alternative. The purpose is to select the Nth type from a list of types, e.g. __type_pack_element<1, char, int, float> is int. We implement it as a special kind of TRAIT_TYPE. For a pathological example tuple_element_t<1000, tuple<2000 types...>> the compilation time is reduced by more than 90% and the memory used by the compiler is reduced by 97%. In realistic examples the gains will be much smaller, but still relevant. Unlike the other built-in traits, __type_pack_element uses template-id syntax instead of call syntax and is SFINAE-enabled, matching Clang's implementation. And like the other built-in traits, it's not mangleable so we can't use it directly in function signatures. N.B. Clang seems to implement __type_pack_element as a first-class template that can e.g. be used as a template-template argument. For simplicity we implement it in a more ad-hoc way. Co-authored-by: Jonathan Wakely <jwakely@redhat.com> PR c++/100157 gcc/cp/ChangeLog: * cp-trait.def (TYPE_PACK_ELEMENT): Define. * cp-tree.h (finish_trait_type): Add complain parameter. * cxx-pretty-print.cc (pp_cxx_trait): Handle CPTK_TYPE_PACK_ELEMENT. * parser.cc (cp_parser_constant_expression): Document default arguments. (cp_parser_trait): Handle CPTK_TYPE_PACK_ELEMENT. Pass tf_warning_or_error to finish_trait_type. * pt.cc (tsubst) <case TRAIT_TYPE>: Handle non-type first argument. Pass complain to finish_trait_type. * semantics.cc (finish_type_pack_element): Define. (finish_trait_type): Add complain parameter. Handle CPTK_TYPE_PACK_ELEMENT. * tree.cc (strip_typedefs): Handle non-type first argument. Pass tf_warning_or_error to finish_trait_type. * typeck.cc (structural_comptypes) <case TRAIT_TYPE>: Use cp_tree_equal instead of same_type_p for the first argument. libstdc++-v3/ChangeLog: * include/bits/utility.h (_Nth_type): Conditionally define in terms of __type_pack_element if available. * testsuite/20_util/tuple/element_access/get_neg.cc: Prune additional errors from the new built-in. gcc/testsuite/ChangeLog: * g++.dg/ext/type_pack_element1.C: New test. * g++.dg/ext/type_pack_element2.C: New test. * g++.dg/ext/type_pack_element3.C: New test.
2023-04-13c++: make cxx_incomplete_type_diagnostic return boolJason Merrill1-4/+4
Like other diagnostic functions that might be silenced by options, it should return whether or not it actually emitted a diagnostic. gcc/cp/ChangeLog: * typeck2.cc (cxx_incomplete_type_diagnostic): Return bool. * cp-tree.h (cxx_incomplete_type_diagnostic): Adjust.
2023-04-01c++: NTTP constraint depending on outer parms [PR109160]Patrick Palka1-1/+2
Here we're crashing during satisfaction for the NTTP 'C<B> auto V' ultimately because convert_template_argument / unify don't pass all outer template arguments to do_auto_deduction, and during satisfaction we need to know all arguments. While these callers do pass some outer arguments, they are only sufficient to properly substitute the (level-lowered) 'auto' and are not necessarily the entire set. Fortunately it seems these callers have access to the full set of outer arguments via convert_template_argument's 'in_decl' parameter and unify's 'tparms' parameter. So this patch adds a new parameter to do_auto_deduction, used only during adc_unify deduction, through which these callers can pass the enclosing (partially instantiated) template and from which do_auto_deduction can obtain _all_ outer template arguments for sake of satisfaction. This patch also ensures that the 'in_decl' argument passed to coerce_template_parms is always a TEMPLATE_DECL, which in turn allows us to pass it as-is to do_auto_deduction; the only coerce_template_parms caller that needed adjustment was tsubst_decl it seems. PR c++/109160 gcc/cp/ChangeLog: * cp-tree.h (do_auto_deduction): Add defaulted tmpl parameter. * pt.cc (convert_template_argument): Pass 'in_decl' as 'tmpl' to do_auto_deduction. (tsubst_decl) <case VAR_/TYPE_DECL>: Pass 'tmpl' instead of 't' as 'in_decl' to coerce_template_parms. (unify) <case TEMPLATE_PARM_INDEX>: Pass TPARMS_PRIMARY_TEMPLATE as 'tmpl' to do_auto_deduction. (do_auto_deduction): Document default arguments. Rename local variable 'tmpl' to 'ctmpl'. Use 'tmpl' to obtain a full set of template arguments for satisfaction in the adc_unify case. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-placeholder12.C: New test.
2023-03-30c++: anonymous union member reference [PR105452]Jason Merrill1-0/+1
While parsing the anonymous union, we don't yet know that it's an anonymous union, so we build the reference to 'v' in the static_assert relative to the union type. But at instantiation time we know it's an anonymous union, so we need to avoid trying to check access for 'v' in the union again; the simplest approach seemed to be to make accessible_p step out to the containing class. While looking at this I also noticed that we were having trouble with DMI in an anonymous union referring to members of the containing class; there we just need to give current_class_ptr the right type. PR c++/105452 gcc/cp/ChangeLog: * search.cc (type_context_for_name_lookup): New. (accessible_p): Handle anonymous union. * init.cc (maybe_instantiate_nsdmi_init): Use type_context_for_name_lookup. * parser.cc (cp_parser_class_specifier): Likewise. * cp-tree.h (type_context_for_name_lookup): Declare. gcc/testsuite/ChangeLog: * g++.dg/lookup/anon8.C: New test.
2023-03-20c++: Drop TREE_READONLY on vars (possibly) initialized by tls wrapper [PR109164]Jakub Jelinek1-0/+1
The following two testcases are miscompiled, because we keep TREE_READONLY on the vars even when they are (possibly) dynamically initialized by a TLS wrapper function. Normally cp_finish_decl drops TREE_READONLY from vars which need dynamic initialization, but for TLS we do this kind of initialization upon every access to those variables. Keeping them TREE_READONLY means e.g. PRE can hoist loads from those before loops which contain the TLS wrapper calls, so we can access the TLS variables before they are initialized. 2023-03-20 Jakub Jelinek <jakub@redhat.com> PR c++/109164 * cp-tree.h (var_needs_tls_wrapper): Declare. * decl2.cc (var_needs_tls_wrapper): No longer static. * decl.cc (cp_finish_decl): Clear TREE_READONLY on TLS variables for which a TLS wrapper will be needed. * g++.dg/tls/thread_local13.C: New test. * g++.dg/tls/thread_local13-aux.cc: New file. * g++.dg/tls/thread_local14.C: New test. * g++.dg/tls/thread_local14-aux.cc: New file.
2023-03-16c++: __func__ and local class DMI [PR105809]Jason Merrill1-0/+1
As in 108242, we need to instantiate in the context of the enclosing function, not after it's gone. PR c++/105809 gcc/cp/ChangeLog: * init.cc (get_nsdmi): Split out... (maybe_instantiate_nsdmi_init): ...this function. * cp-tree.h: Declare it. * pt.cc (tsubst_expr): Use it. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-__func__3.C: New test.
2023-03-09c++: add __is_deducible trait [PR105841]Jason Merrill1-0/+1
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-03c++, v3: Emit fundamental tinfos for _Float16/decltype(0.0bf16) types on ↵Jakub Jelinek1-11/+0
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-01c++: unevaluated array new-expr size constantness [PR108219]Patrick Palka1-0/+1
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-02-17c++: make manifestly_const_eval tri-statePatrick Palka1-1/+19
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-16c++: TYPENAME_TYPE lookup ignoring non-types [PR107773]Patrick Palka1-0/+3
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-05c++: equivalence of non-dependent calls [PR107461]Patrick Palka1-0/+1
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.
2023-01-31c++: fix ICE with -Wduplicated-cond [PR107593]Marek Polacek1-1/+0
Here we crash because a CAST_EXPR, representing T(), doesn't have its operand, and operand_equal_p's STRIP_ANY_LOCATION_WRAPPER doesn't expect that. (o_e_p is called from warn_duplicated_cond_add_or_warn.) In the past we've adjusted o_e_p to better cope with template codes, but in this case I think we just want to avoid attempting to warn about inst-dependent expressions; I don't think I've ever envisioned -Wduplicated-cond to warn about them. Also destroy the chain when an inst-dependent expression is encountered to not warn in Wduplicated-cond4.C. The ICE started with r12-6022, two-stage name lookup for overloaded operators, which gave dependent operators a TREE_TYPE (in particular, DEPENDENT_OPERATOR_TYPE), so we no longer bail out here in o_e_p: /* Similar, if either does not have a type (like a template id), they aren't equal. */ if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) return false; PR c++/107593 PR c++/108597 gcc/c-family/ChangeLog: * c-common.h (instantiation_dependent_expression_p): Declare. * c-warn.cc (warn_duplicated_cond_add_or_warn): If the condition is dependent, invalidate the chain. gcc/c/ChangeLog: * c-objc-common.cc (instantiation_dependent_expression_p): New. gcc/cp/ChangeLog: * cp-tree.h (instantiation_dependent_expression_p): Don't declare here. gcc/testsuite/ChangeLog: * g++.dg/warn/Wduplicated-cond3.C: New test. * g++.dg/warn/Wduplicated-cond4.C: New test. * g++.dg/warn/Wduplicated-cond5.C: New test.
2023-01-19c++: Fix up handling of non-dependent subscript with static operator[] ↵Jakub Jelinek1-0/+1
[PR108437] As the following testcases shows, when adding static operator[] support I've missed that the 2 build_min_non_dep_op_overload functions need to be adjusted. The first one we only use for the single index case, but as cp_tree_code_length (ARRAY_REF) is 2, we were running into an assertion there which compared nargs and expected_nargs. For ARRAY_REF, the operator[] is either a non-static member or newly static member, never out of class and for the static member case if user uses single index the operator[] needs to have a single argument as well, but the function is called with 2 - the object it is invoked on and the index. We need to evaluate side-effects of the object and use just a single argument in the call - the index. The other build_min_non_dep_op_overload overload has been added solely for ARRAY_REF - CALL_EXPR is the other operator that accepts variable number of operands but that one goes through different routines. There we asserted it is a METHOD_TYPE, so again we shouldn't assert that but handle the case when it is not one by making sure object's side-effects are evaluated if needed and passing all the index arguments to the static operator[]. 2023-01-19 Jakub Jelinek <jakub@redhat.com> PR c++/108437 * cp-tree.h (keep_unused_object_arg): Declare. * call.cc (keep_unused_object_arg): No longer static. * tree.cc (build_min_non_dep_op_overload): Handle ARRAY_REF with overload being static member function. * g++.dg/cpp23/subscript12.C: New test. * g++.dg/cpp23/subscript13.C: New test.
2023-01-16Update copyright years.Jakub Jelinek1-1/+1
2022-12-23c++: template friend with variadic constraints [PR107853]Patrick Palka1-0/+1
When instantiating a constrained hidden template friend, we substitute into its template-head requirements in tsubst_friend_function. For this substitution we use the template's full argument vector whose outer levels correspond to the instantiated class's arguments and innermost level corresponds to the template's own level-lowered generic arguments. But for A<int>::f here, for which the relevant argument vector is {{int}, {Us...}}, the substitution into (C<Ts, Us> && ...) triggers the assert in use_pack_expansion_extra_args_p since one argument is a pack expansion and the other isn't. And for A<int, int>::f, for which the relevant argument vector is {{int, int}, {Us...}}, the use_pack_expansion_extra_args_p assert would also trigger but we first get a bogus "mismatched argument pack lengths" error from tsubst_pack_expansion. Sidestepping the question of whether tsubst_pack_expansion should be able to handle such substitutions, it seems we can work around this by using only the instantiated class's arguments and not also the template friend's own generic arguments, which is consistent with how we normally substitute into the signature of a member template. PR c++/107853 gcc/cp/ChangeLog: * constraint.cc (maybe_substitute_reqs_for): Substitute into the template-head requirements of a template friend using only its outer arguments via outer_template_args. * cp-tree.h (outer_template_args): Declare. * pt.cc (outer_template_args): Define, factored out and generalized from ... (ctor_deduction_guides_for): ... here. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-friend12.C: New test. * g++.dg/cpp2a/concepts-friend13.C: New test.
2022-12-19c++: modules and std::source_location::current() def arg [PR100881]Patrick Palka1-6/+2
We currently declare __builtin_source_location with a const void* return type instead of the actual type const std::source_location::__impl*, and later when folding this builtin we obtain the actual type via name lookup. But the below testcase demonstrates this approach seems to interact poorly with modules, since we may import an entity that uses std::source_location::current() in its default argument (or DMI) without necessarily importing <source_location>, and thus the name lookup for std::source_location will fail at the call site (when using the default argument) unless we also import <source_location>. This patch fixes this by instead initially declaring the builtin with an auto return type and updating it appropriately upon its first use (in standard code the first/only use would be in the definition of std::source_location). Thus when folding calls to this builtin we can get at its return type through the type of the CALL_EXPR and avoid needing to do a name lookup. PR c++/100881 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_builtin_function_call): Adjust calls to fold_builtin_source_location. * cp-gimplify.cc (cp_gimplify_expr): Likewise. (cp_fold): Likewise. (get_source_location_impl_type): Remove location_t parameter and adjust accordingly. No longer static. (fold_builtin_source_location): Take a CALL_EXPR tree instead of a location and obtain the impl type from its return type. * cp-tree.h (enum cp_tree_index): Remove CPTI_SOURCE_LOCATION_IMPL enumerator. (source_location_impl): Remove. (fold_builtin_source_location): Adjust parameter type. (get_source_location_impl_type): Declare. * decl.cc (cxx_init_decl_processing): Declare __builtin_source_location with auto return type instead of const void*. (require_deduced_type): Update the return type of __builtin_source_location. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/srcloc3.C: Adjust expected note s/evaluating/using. * g++.dg/cpp2a/srcloc4.C: Likewise. * g++.dg/cpp2a/srcloc5.C: Likewise. * g++.dg/cpp2a/srcloc6.C: Likewise. * g++.dg/cpp2a/srcloc7.C: Likewise. * g++.dg/cpp2a/srcloc8.C: Likewise. * g++.dg/cpp2a/srcloc9.C: Likewise. * g++.dg/cpp2a/srcloc10.C: Likewise. * g++.dg/cpp2a/srcloc11.C: Likewise. * g++.dg/cpp2a/srcloc12.C: Likewise. * g++.dg/cpp2a/srcloc13.C: Likewise. * g++.dg/modules/pr100881_a.C: New test. * g++.dg/modules/pr100881_b.C: New test.
2022-12-08c++: avoid initializer_list<string> [PR105838]Jason Merrill1-0/+1
When constructing a vector<string> from { "strings" }, first is built an initializer_list<string>, which is then copied into the strings in the vector. But this is inefficient: better would be treat the { "strings" } as a range and construct the strings in the vector directly from the string-literals. We can do this transformation for standard library classes because we know the design patterns they follow. PR c++/105838 gcc/cp/ChangeLog: * call.cc (list_ctor_element_type): New. (braced_init_element_type): New. (has_non_trivial_temporaries): New. (maybe_init_list_as_array): New. (maybe_init_list_as_range): New. (build_user_type_conversion_1): Use maybe_init_list_as_range. * parser.cc (cp_parser_braced_list): Call recompute_constructor_flags. * cp-tree.h (find_temps_r): Declare. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/initlist-opt1.C: New test.
2022-12-08c++: fewer allocator temps [PR105838]Jason Merrill1-0/+1
In this PR, initializing the array of std::string to pass to the vector initializer_list constructor gets very confusing to the optimizers as the number of elements increases, primarily because of all the std::allocator temporaries passed to all the string constructors. Instead of creating one for each string, let's share an allocator between all the strings; we can do this safely because we know that std::allocator is stateless and that string doesn't care about the object identity of its allocator parameter. PR c++/105838 gcc/cp/ChangeLog: * cp-tree.h (is_std_allocator): Declare. * constexpr.cc (is_std_allocator): Split out from... (is_std_allocator_allocate): ...here. * init.cc (find_temps_r): New. (find_allocator_temp): New. (build_vec_init): Use it. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/allocator-opt1.C: New test.
2022-12-01c++: comptypes ICE with BOUND_TEMPLATE_TEMPLATE_PARMs [PR107539]Patrick Palka1-2/+8
Here we end up giving the two BOUND_TEMPLATE_TEMPLATE_PARMs C<decltype(f::t)> and C<decltype(g::t)> the same TYPE_CANONICAL because the hash table that interns TYPE_CANONICAL for template type parameters doesn't set the comparing_specializations flag which controls how PARM_DECLs from different contexts compare equal. Later, from spec_hasher::equal for the corresponding two specializations A<C<decltype(f::t)>> and A<C<decltype(g::t)>>, we compare the two bound ttps with comparing_specializations set hence they now (structurally) compare different despite having the same TYPE_CANONICAL, and so we get the error: internal compiler error: same canonical type node for different types 'C<decltype (t)>' and 'C<decltype (t)>' This suggests that we should be setting comparing_specializations from ctp_hasher::equal to match spec_hasher::equal. But doing so introduces a separate ICE in cpp2a/concepts-placeholder3.C: internal compiler error: canonical types differ for identical types 'auto [requires ::same_as<<placeholder>, decltype(f::x)>]' and 'auto [requires ::same_as<<placeholder>, decltype(g::x)>]' because norm_hasher::equal doesn't set comparing_specializations either. I'm not sure when exactly we need to set comparing_specializations given what it controls (TYPENAME_TYPE equality/hashing and PARM_DECL equality) but it seems to be the conservative choice to set the flag wherever we have a global hash table that relies on type equality. To that end this patch sets comparing_specializations in ctp_hasher and norm_hasher, as well as in atom_hasher and sat_hasher for good measure. This turns out to be a compile time win of about 2% in some concepts tests, probably because of the improved TYPENAME_TYPE hashing enabled by the flag. PR c++/107539 gcc/cp/ChangeLog: * constraint.cc (norm_hasher::hash, norm_hasher::equal): Set comparing_specializations. (sat_hasher::hash, sat_hasher::equal): Likewise. * cp-tree.h (atom_hasher::hash, atom_hasher::equal): Likewise. * pt.cc (ctp_hasher::hash, ctp_hasher::equal): Likewise. gcc/testsuite/ChangeLog: * g++.dg/template/canon-type-19.C: New test.
2022-11-18c++: implement P1492 contractsJeff Chapman II1-0/+64
Implement the P1492 versions of contracts, along with extensions that support the emulation of N4820 and other proposals. This implementation assigns a concrete semantic (one of: ignore, assume, enforce, or observe) to each contract attribute depending on its labels and configuration options. Co-authored-by: Andrew Sutton <asutton@lock3software.com> Co-authored-by: Andrew Marmaduke <amarmaduke@lock3software.com> Co-authored-by: Michael Lopez <mlopez@lock3software.com> Co-authored-by: Jason Merrill <jason@redhat.com> gcc/ChangeLog: * doc/invoke.texi: Document contracts flags. gcc/c-family/ChangeLog: * c.opt: Add contracts flags. * c-cppbuiltin.cc (c_cpp_builtins): Add contracts feature-test macros. gcc/cp/ChangeLog: * cp-tree.h (enum cp_tree_index): Add CPTI_PSEUDO_CONTRACT_VIOLATION. (pseudo_contract_violation_type): New macro. (struct saved_scope): Add x_processing_contract_condition. (processing_contract_condition): New macro. (comparing_override_contracts): New variable decl. (find_contract): New inline. (set_decl_contracts): New inline. (get_contract_semantic): New inline. (set_contract_semantic): New inline. * constexpr.cc (cxx_eval_assert): Split out from... (cxx_eval_internal_function): ...here. (cxx_eval_constant_expression): Use it for contracts. (potential_constant_expression_1): Handle contracts. * cp-gimplify.cc (cp_genericize_r): Handle contracts. * cp-objcp-common.cc (cp_tree_size): Handle contracts. (cp_common_init_ts): Handle contracts. (cp_handle_option): Handle contracts. * decl.cc (duplicate_decls): Handle contracts. (check_tag_decl): Check for bogus contracts. (start_decl): Check flag_contracts. (grokfndecl): Call rebuild_postconditions. (grokdeclarator): Handle contract attributes. (start_preparsed_function): Call start_function_contracts. (finish_function): Call finish_function_contracts. * decl2.cc (cp_check_const_attributes): Skip contracts. (comdat_linkage): Handle outlined contracts. * error.cc (dump_type): Handle null TYPE_IDENTIFIER. * g++spec.cc (EXPERIMENTAL): New macro. (lang_specific_driver): Add -lstdc++exp if -fcontracts. * mangle.cc (write_encoding): Handle outlined contracts. * module.cc (trees_out::fn_parms_init): Handle outlined contracts. (trees_in::fn_parms_init): Likewise. (check_mergeable_decl): Likewise. (module_state_config::get_dialect): Record -fcontracts. * parser.h (struct cp_unparsed_functions_entry): Add contracts. * parser.cc (unparsed_contracts): New macro. (push_unparsed_function_queues): Adjust. (contract_attribute_p): New. (cp_parser_statement): Check contracts. (cp_parser_decl_specifier_seq): Handle contracts. (cp_parser_skip_to_closing_square_bracket): Split out... (cp_parser_skip_up_to_closing_square_bracket): ...this fn. (cp_parser_class_specifier): Do contract late parsing. (cp_parser_class_head): Check contracts. (cp_parser_contract_role): New. (cp_parser_contract_mode_opt): New. (find_error, contains_error_p): New. (cp_parser_contract_attribute_spec): New. (cp_parser_late_contract_condition): New. (cp_parser_std_attribute_spec): Handle contracts. (cp_parser_save_default_args): Also save contracts. * pt.cc (register_parameter_specializations): No longer static. (register_local_identity): New. (check_explicit_specialization): Call remove_contract_attributes. (tsubst_contract, tsubst_contract_attribute): New. (tsubst_contract_attributes): New. (tsubst_attribute): Add comment. (tsubst_copy): Also allow parm when processing_contract_condition. (tsubst_expr): Handle contracts. (regenerate_decl_from_template): Handle contracts. * search.cc (check_final_overrider): Compare contracts. * semantics.cc (set_cleanup_locs): Skip POSTCONDITION_STMT. (finish_non_static_data_member): Check contracts. (finish_this_expr): Check contracts. (process_outer_var_ref): Handle contracts. (finish_id_expression_1): Handle contracts. (apply_deduced_return_type): Adjust contracts. * tree.cc (handle_contract_attribute): New. (get_innermost_component, is_this_expression): New. (comparing_this_references): New. (equivalent_member_references): New. (cp_tree_equal): Check it. * typeck.cc (check_return_expr): Apply contracts. * Make-lang.in: Add contracts.o. * config-lang.in: Add contracts.cc. * cp-tree.def (ASSERTION_STMT, PRECONDITION_STMT) (POSTCONDITION_STMT): New. * contracts.h: New file. * contracts.cc: New file. gcc/testsuite/ChangeLog: * g++.dg/modules/modules.exp: Pass dg-options to link command. * lib/g++.exp: Add -L for libstdc++exp.a. * g++.dg/contracts/backtrace_handler/assert_fail.cpp: New test. * g++.dg/contracts/backtrace_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/contracts-access1.C: New test. * g++.dg/contracts/contracts-assume1.C: New test. * g++.dg/contracts/contracts-assume2.C: New test. * g++.dg/contracts/contracts-assume3.C: New test. * g++.dg/contracts/contracts-assume4.C: New test. * g++.dg/contracts/contracts-assume5.C: New test. * g++.dg/contracts/contracts-assume6.C: New test. * g++.dg/contracts/contracts-comdat1.C: New test. * g++.dg/contracts/contracts-config1.C: New test. * g++.dg/contracts/contracts-constexpr1.C: New test. * g++.dg/contracts/contracts-constexpr2.C: New test. * g++.dg/contracts/contracts-constexpr3.C: New test. * g++.dg/contracts/contracts-conversion1.C: New test. * g++.dg/contracts/contracts-ctor-dtor1.C: New test. * g++.dg/contracts/contracts-ctor-dtor2.C: New test. * g++.dg/contracts/contracts-cv1.C: New test. * g++.dg/contracts/contracts-deduced1.C: New test. * g++.dg/contracts/contracts-deduced2.C: New test. * g++.dg/contracts/contracts-friend1.C: New test. * g++.dg/contracts/contracts-ft1.C: New test. * g++.dg/contracts/contracts-ignore1.C: New test. * g++.dg/contracts/contracts-ignore2.C: New test. * g++.dg/contracts/contracts-large-return.C: New test. * g++.dg/contracts/contracts-multiline1.C: New test. * g++.dg/contracts/contracts-multiple-inheritance1.C: New test. * g++.dg/contracts/contracts-multiple-inheritance2.C: New test. * g++.dg/contracts/contracts-nested-class1.C: New test. * g++.dg/contracts/contracts-nested-class2.C: New test. * g++.dg/contracts/contracts-nocopy1.C: New test. * g++.dg/contracts/contracts-override.C: New test. * g++.dg/contracts/contracts-post1.C: New test. * g++.dg/contracts/contracts-post2.C: New test. * g++.dg/contracts/contracts-post3.C: New test. * g++.dg/contracts/contracts-post4.C: New test. * g++.dg/contracts/contracts-post5.C: New test. * g++.dg/contracts/contracts-post6.C: New test. * g++.dg/contracts/contracts-pre1.C: New test. * g++.dg/contracts/contracts-pre10.C: New test. * g++.dg/contracts/contracts-pre2.C: New test. * g++.dg/contracts/contracts-pre2a1.C: New test. * g++.dg/contracts/contracts-pre2a2.C: New test. * g++.dg/contracts/contracts-pre3.C: New test. * g++.dg/contracts/contracts-pre4.C: New test. * g++.dg/contracts/contracts-pre5.C: New test. * g++.dg/contracts/contracts-pre6.C: New test. * g++.dg/contracts/contracts-pre7.C: New test. * g++.dg/contracts/contracts-pre9.C: New test. * g++.dg/contracts/contracts-redecl1.C: New test. * g++.dg/contracts/contracts-redecl2.C: New test. * g++.dg/contracts/contracts-redecl3.C: New test. * g++.dg/contracts/contracts-redecl4.C: New test. * g++.dg/contracts/contracts-redecl5.C: New test. * g++.dg/contracts/contracts-redecl6.C: New test. * g++.dg/contracts/contracts-redecl7.C: New test. * g++.dg/contracts/contracts-redecl8.C: New test. * g++.dg/contracts/contracts-tmpl-attr1.C: New test. * g++.dg/contracts/contracts-tmpl-spec1.C: New test. * g++.dg/contracts/contracts-tmpl-spec2.C: New test. * g++.dg/contracts/contracts-tmpl-spec3.C: New test. * g++.dg/contracts/contracts1.C: New test. * g++.dg/contracts/contracts10.C: New test. * g++.dg/contracts/contracts11.C: New test. * g++.dg/contracts/contracts12.C: New test. * g++.dg/contracts/contracts13.C: New test. * g++.dg/contracts/contracts14.C: New test. * g++.dg/contracts/contracts15.C: New test. * g++.dg/contracts/contracts16.C: New test. * g++.dg/contracts/contracts17.C: New test. * g++.dg/contracts/contracts18.C: New test. * g++.dg/contracts/contracts19.C: New test. * g++.dg/contracts/contracts2.C: New test. * g++.dg/contracts/contracts20.C: New test. * g++.dg/contracts/contracts22.C: New test. * g++.dg/contracts/contracts24.C: New test. * g++.dg/contracts/contracts25.C: New test. * g++.dg/contracts/contracts3.C: New test. * g++.dg/contracts/contracts35.C: New test. * g++.dg/contracts/contracts4.C: New test. * g++.dg/contracts/contracts5.C: New test. * g++.dg/contracts/contracts6.C: New test. * g++.dg/contracts/contracts7.C: New test. * g++.dg/contracts/contracts8.C: New test. * g++.dg/contracts/contracts9.C: New test. * g++.dg/modules/contracts-1_a.C: New test. * g++.dg/modules/contracts-1_b.C: New test. * g++.dg/modules/contracts-2_a.C: New test. * g++.dg/modules/contracts-2_b.C: New test. * g++.dg/modules/contracts-2_c.C: New test. * g++.dg/modules/contracts-3_a.C: New test. * g++.dg/modules/contracts-3_b.C: New test. * g++.dg/modules/contracts-4_a.C: New test. * g++.dg/modules/contracts-4_b.C: New test. * g++.dg/modules/contracts-4_c.C: New test. * g++.dg/modules/contracts-4_d.C: New test. * g++.dg/modules/contracts-tpl-friend-1_a.C: New test. * g++.dg/modules/contracts-tpl-friend-1_b.C: New test. * g++.dg/contracts/backtrace_handler/Makefile: New test. * g++.dg/contracts/backtrace_handler/README: New test. * g++.dg/contracts/backtrace_handler/example_out.txt: New test. * g++.dg/contracts/backtrace_handler/example_pretty.txt: New test. * g++.dg/contracts/backtrace_handler/prettytrace.sh: New test. * g++.dg/contracts/except_preload_handler/Makefile: New test. * g++.dg/contracts/except_preload_handler/README: New test. * g++.dg/contracts/except_preload_handler/assert_fail.cpp: New test. * g++.dg/contracts/except_preload_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/noexcept_preload_handler/Makefile: New test. * g++.dg/contracts/noexcept_preload_handler/README: New test. * g++.dg/contracts/noexcept_preload_handler/assert_fail.cpp: New test. * g++.dg/contracts/noexcept_preload_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/preload_handler/Makefile: New test. * g++.dg/contracts/preload_handler/README: New test. * g++.dg/contracts/preload_handler/assert_fail.cpp: New test. * g++.dg/contracts/preload_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/preload_nocontinue_handler/Makefile: New test. * g++.dg/contracts/preload_nocontinue_handler/README: New test. * g++.dg/contracts/preload_nocontinue_handler/assert_fail.cpp: New test. * g++.dg/contracts/preload_nocontinue_handler/handle_contract_violation.cpp: New test. * g++.dg/contracts/preload_nocontinue_handler/nocontinue.cpp: New test.
2022-11-16c++: P2448 - Relaxing some constexpr restrictions [PR106649]Marek Polacek1-0/+1
This patch implements C++23 P2448, which lifts more restrictions on the constexpr keyword. It's effectively going the way of being just a hint (hello, inline!). This gist is relatively simple: in C++23, a constexpr function's return type/parameter type doesn't have to be a literal type; and you can have a constexpr function for which no invocation satisfies the requirements of a core constant expression. For example, void f(int& i); // not constexpr constexpr void g(int& i) { f(i); // unconditionally calls a non-constexpr function } is now OK, even though there isn't an invocation of 'g' that would be a constant expression. Maybe 'f' will be made constexpr soon, or maybe this depends on the version of C++ used, and similar. The patch is unfortunately not that trivial. The important bit is to use the new require_potential_rvalue_constant_expression_fncheck in maybe_save_constexpr_fundef (and where appropriate). It has a new flag that says that we're checking the body of a constexpr function, and in that case it's OK to find constructs that aren't a constant expression. Since it's useful to be able to check for problematic constructs even in C++23, this patch implements a new warning, -Winvalid-constexpr, which is a pedwarn turned on by default in C++20 and earlier, and which can be turned on in C++23 as well, in which case it's an ordinary warning. This I implemented by using the new function constexpr_error, used in p_c_e_1 and friends. (In some cases I believe fundef_p will be always false (= hard error), but it made sense to me to be consistent and use constexpr_error throughout p_c_e_1.) While working on this I think I found a bug, see constexpr-nonlit15.C and <https://gcc.gnu.org/PR107598>. This patch doesn't address that. This patch includes changes to diagnose the problem if the user doesn't use -Winvalid-constexpr and calls a constexpr function that in fact isn't constexpr-ready yet: maybe_save_constexpr_fundef registers the function if warn_invalid_constexpr is 0 and explain_invalid_constexpr_fn then gives the diagnostic. PR c++/106649 gcc/c-family/ChangeLog: * c-cppbuiltin.cc (c_cpp_builtins): Update value of __cpp_constexpr for C++23. * c-opts.cc (c_common_post_options): Set warn_invalid_constexpr depending on cxx_dialect. * c.opt (Winvalid-constexpr): New option. gcc/cp/ChangeLog: * constexpr.cc (constexpr_error): New function. (is_valid_constexpr_fn): Use constexpr_error. (maybe_save_constexpr_fundef): Call require_potential_rvalue_constant_expression_fncheck rather than require_potential_rvalue_constant_expression. Register the function if -Wno-invalid-constexpr was specified. (explain_invalid_constexpr_fn): Don't return early if a function marked 'constexpr' that isn't actually a constant expression was called. (non_const_var_error): Add a bool parameter. Use constexpr_error. (inline_asm_in_constexpr_error): Likewise. (cxx_eval_constant_expression): Adjust calls to non_const_var_error and inline_asm_in_constexpr_error. (potential_constant_expression_1): Add a bool parameter. Use constexpr_error. (require_potential_rvalue_constant_expression_fncheck): New function. * cp-tree.h (require_potential_rvalue_constant_expression_fncheck): Declare. * method.cc (struct comp_info): Call require_potential_rvalue_constant_expression_fncheck rather than require_potential_rvalue_constant_expression. gcc/ChangeLog: * doc/invoke.texi: Document -Winvalid-constexpr. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-ctor2.C: Expect an error in c++20_down only. * g++.dg/cpp0x/constexpr-default-ctor.C: Likewise. * g++.dg/cpp0x/constexpr-diag3.C: Likewise. * g++.dg/cpp0x/constexpr-ex1.C: Likewise. * g++.dg/cpp0x/constexpr-friend.C: Likewise. * g++.dg/cpp0x/constexpr-generated1.C: Likewise. * g++.dg/cpp0x/constexpr-ice5.C: Likewise. * g++.dg/cpp0x/constexpr-ice6.C: Likewise. * g++.dg/cpp0x/constexpr-memfn1.C: Likewise. * g++.dg/cpp0x/constexpr-neg2.C: Likewise. * g++.dg/cpp0x/constexpr-non-const-arg.C: Likewise. * g++.dg/cpp0x/constexpr-reinterpret1.C: Likewise. * g++.dg/cpp0x/pr65327.C: Likewise. * g++.dg/cpp1y/constexpr-105050.C: Likewise. * g++.dg/cpp1y/constexpr-89285-2.C: Likewise. * g++.dg/cpp1y/constexpr-89285.C: Likewise. * g++.dg/cpp1y/constexpr-89785-2.C: Likewise. * g++.dg/cpp1y/constexpr-neg1.C: Likewise. * g++.dg/cpp1y/constexpr-nsdmi7b.C: Likewise. * g++.dg/cpp1y/constexpr-throw.C: Likewise. * g++.dg/cpp23/constexpr-nonlit3.C: Remove dg-error. * g++.dg/cpp23/constexpr-nonlit6.C: Call the test functions. * g++.dg/cpp23/feat-cxx2b.C: Adjust the expected value of __cpp_constexpr. * g++.dg/cpp2a/consteval3.C: Remove dg-error. * g++.dg/cpp2a/constexpr-new7.C: Expect an error in c++20_down only. * g++.dg/cpp2a/constexpr-try5.C: Remove dg-error. * g++.dg/cpp2a/spaceship-constexpr1.C: Expect an error in c++20_down only. * g++.dg/cpp2a/spaceship-eq3.C: Likewise. * g++.dg/diagnostic/constexpr1.C: Remove dg-error. * g++.dg/gomp/pr79664.C: Use -Winvalid-constexpr -pedantic-errors. * g++.dg/ubsan/vptr-4.C: Likewise. * g++.dg/cpp23/constexpr-nonlit10.C: New test. * g++.dg/cpp23/constexpr-nonlit11.C: New test. * g++.dg/cpp23/constexpr-nonlit12.C: New test. * g++.dg/cpp23/constexpr-nonlit13.C: New test. * g++.dg/cpp23/constexpr-nonlit14.C: New test. * g++.dg/cpp23/constexpr-nonlit15.C: New test. * g++.dg/cpp23/constexpr-nonlit16.C: New test. * g++.dg/cpp23/constexpr-nonlit8.C: New test. * g++.dg/cpp23/constexpr-nonlit9.C: New test.
2022-11-16c++: Allow attributes on concepts - DR 2428Jakub Jelinek1-1/+1
The following patch adds parsing of attributes to concept definition, allows deprecated attribute to be specified (as CONCEPT_DECL now needs to be checked in c-family/c-attribs.cc, I had to move its declaration from cp/*.def to c-family/*.def) and checks TREE_DEPRECATED in build_standard_check (not sure if that is the right spot, or whether it shouldn't be checked also for variable and function concepts and how to write testcase coverage for that). 2022-11-16 Jakub Jelinek <jakub@redhat.com> gcc/c-family/ * c-common.def (CONCEPT_DECL): New tree, moved here from cp-tree.def. * c-common.cc (c_common_init_ts): Handle CONCEPT_DECL. * c-attribs.cc (handle_deprecated_attribute): Allow deprecated attribute on CONCEPT_DECL. gcc/cp/ * cp-tree.def (CONCEPT_DECL): Move to c-common.def. * cp-objcp-common.cc (cp_common_init_ts): Don't handle CONCEPT_DECL here. * cp-tree.h (finish_concept_definition): Add ATTRS parameter. * parser.cc (cp_parser_concept_definition): Parse attributes in between identifier and =. Adjust finish_concept_definition caller. * pt.cc (finish_concept_definition): Add ATTRS parameter. Call cplus_decl_attributes. * constraint.cc (build_standard_check): If CONCEPT_DECL is TREE_DEPRECATED, emit -Wdeprecated-declaration warnings. gcc/testsuite/ * g++.dg/cpp2a/concepts-dr2428.C: New test.