aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/concepts
AgeCommit message (Collapse)AuthorFilesLines
2022-04-15c++: wrong error with variadic concept [PR105268]Marek Polacek1-0/+20
Here we issue a wrong error for the template<typename T = S<C_many<int>>> void g(); line in the testcase. I surmise that's because we mistakenly parse C_many<int> as a placeholder-type-specifier, and things go wrong from there. We are in a default argument so we should reject parsing C_many<int> as a placeholder-type-specifier, which would mean creating a new parameter. We want C_many<int> to be a concept-id instead. It's interesting to see why the same problem didn't occur for C_one<int>. In that case, cp_parser_placeholder_type_specifier -> finish_type_constraints -> build_type_constraint -> build_concept_check -> build_standard_check -> coerce_template_parms fails the parse here: 8916 nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; 8917 if ((nargs - variadic_args_p > nparms && !variadic_p) 8918 || (nargs < nparms - variadic_p 8919 && require_all_args 8920 && !variadic_args_p 8921 && (!use_default_args 8922 || (TREE_VEC_ELT (parms, nargs) != error_mark_node 8923 && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))) 8924 { 8925 bad_nargs: ... 8943 return error_mark_node; because nargs is 2 (the targs are <WILDCARD_DECL, int>) while nparms is 1 (for the one 'typename' in the tparam list of C_one). But for C_many<int> variadic_p is true so we don't return error_mark_node but <type_argument_pack>. This patch does not issue any error for the !tentative case because I didn't figure out how to trigger that. So it adds an assert instead. PR c++/105268 gcc/cp/ChangeLog: * parser.cc (cp_parser_placeholder_type_specifier): Return error_mark_node when trying to build up a constrained parameter in a default argument. gcc/testsuite/ChangeLog: * g++.dg/concepts/variadic6.C: New test.
2022-03-30c++: Fox template-introduction tentative parsing in class bodies clear ↵Jakub Jelinek1-0/+13
colon_corrects_to_scope_p [PR105061] The concepts support (in particular template introductions from concepts TS) broke the following testcase, valid unnamed bitfields with dependent types (or even just typedefs) were diagnosed as typos (: instead of correct ::) in template introduction during their tentative parsing. The following patch fixes that by not doing this : to :: correction when member_p is true. 2022-03-30 Jakub Jelinek <jakub@redhat.com> PR c++/105061 * parser.cc (cp_parser_template_introduction): If member_p, temporarily clear parser->colon_corrects_to_scope_p around tentative parsing of nested name specifier. * g++.dg/concepts/pr105061.C: New test.
2022-03-12c++: give fold expressions a locationPatrick Palka1-4/+4
This improves diagnostic quality for unsatisfied atomic constraints that consist of a fold expression, e.g. in concepts/diagnostic3.C the "evaluated to false" diagnostic now points to the expression: .../diagnostic3.C:10:22: note: the expression ‘(foo<Ts> && ...) [with Ts = {int, char}]’ evaluated to ‘false’ 10 | requires (foo<Ts> && ...) | ~~~~~~~~~~~~^~~~ gcc/cp/ChangeLog: * semantics.cc (finish_unary_fold_expr): Use input_location instead of UNKNOWN_LOCATION. (finish_binary_fold_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic3.C: Adjusted expected location of "evaluated to false" diagnostics.
2021-12-14c++: processing_template_decl vs template depth [PR103408]Patrick Palka1-2/+2
We use processing_template_decl in two slightly different ways: as a flag to signal that we're dealing with templated trees, and as a measure of the current syntactic template nesting depth. This overloaded meaning of p_t_d is conceptually confusing and leads to bugs that we end up working around in an ad-hoc fashion. This patch replaces all uses of processing_template_decl that care about its magnitude to instead look at the depth of current_template_parms via a new macro current_template_depth. This allows us to eliminate 3 workarounds in the concepts code: two about non-templated requires-expressions (in constraint.cc) and one about lambdas inside constraints (in cp_parser_requires_clause_expression etc). This also fixes the testcase in PR103408 about auto(x) used inside a non-templated requires-expression. The replacement was mostly mechanical, aside from two issues: * In synthesize_implicit_template_parm, when introducing a new template parameter list for an abbreviated function template, we need to add the new level of current_template_parms sooner, before calling process_template_parm, since this latter function now looks at current_template_depth to determine the level of the new parameter. * In instantiate_class_template_1 after substituting a template friend declaration, we currently increment processing_template_decl around the call to make_friend_class so that the friend_depth computation within this subroutine yields a nonzero value. We could just replace this with an equivalent manipulation of current_template_depth, but this patch instead rewrites the friend_depth calculation within make_friend_class to not depend on p_t_d / c_t_d at all when called from instantiate_class_template_1. PR c++/103408 gcc/cp/ChangeLog: * constraint.cc (type_deducible_p): Remove workaround for non-templated requires-expressions. (normalize_placeholder_type_constraints): Likewise. * cp-tree.h (current_template_depth): Define. (PROCESSING_REAL_TEMPLATE_DECL): Inspect current_template_depth instead of the magnitude of processing_template_decl. * decl.c (start_decl): Likewise. (grokfndecl): Likewise. (grokvardecl): Likewise. (grokdeclarator): Likewise. * friend.c (make_friend_class): Likewise. Calculate friend_depth differently when called at instantiation time instead of parse time. (do_friend): Likewise. * parser.c (cp_parser_requires_clause_expression): Remove workaround for lambdas inside constraints. (cp_parser_constraint_expression): Likewise. (cp_parser_requires_expression): Likewise. (synthesize_implicit_template_parm): Add to current_template_parms before calling process_template_parm. * pt.c (inline_needs_template_parms): Inspect current_template_depth instead of the magnitude of processing_template_decl. (push_inline_template_parms_recursive): Likewise. (maybe_begin_member_template_processing): Likewise. (begin_template_parm_list): Likewise. (process_template_parm): Likewise. (end_template_parm_list): Likewise. (push_template_decl): Likewise. (add_inherited_template_parms): Likewise. (instantiate_class_template_1): Don't adjust processing_template_decl around the call to make_friend_class. adjust_processing_template_decl to adjust_template_depth. Set current_template_parms instead of processing_template_decl when adjust_template_depth. (make_auto_1): Inspect current_template_depth instead of the magnitude of processing_template_decl. (splice_late_return_type): Likewise. * semantics.c (fixup_template_type): Likewise. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic18.C: Expect a "constraints on a non-templated function" error. * g++.dg/cpp23/auto-fncast11.C: New test.
2021-07-09c++: concepts TS and explicit specialization [PR101098]Jason Merrill1-0/+9
duplicate_decls was not recognizing the explicit specialization as matching the implicit specialization of g<Y> because function_requirements_equivalent_p was seeing the C constraint on the implicit one and not on the explicit. PR c++/101098 gcc/cp/ChangeLog: * decl.c (function_requirements_equivalent_p): Only compare trailing requirements on a specialization. gcc/testsuite/ChangeLog: * g++.dg/concepts/explicit-spec1.C: New test.
2021-05-03c++: Fix ICE with invalid requires-expression [PR100055]Marek Polacek1-0/+7
This fixes a crash on invalid requires-expression: in this test, current_template_parms is null so accessing TEMPLATE_PARMS_CONSTRAINTS is going to fail. So don't crash, but make sure we've complained already. gcc/cp/ChangeLog: PR c++/100055 * decl.c (grokfndecl): Check current_template_parms. gcc/testsuite/ChangeLog: PR c++/100055 * g++.dg/concepts/diagnostic18.C: New test.
2021-04-23c++: Fix pretty printing pointer to function type [PR98767]Patrick Palka1-0/+17
When pretty printing a pointer to function type, pp_cxx_parameter_declaration_clause ends up always outputting an empty function parameter list because the loop that outputs the list iterates over 'args' instead of 'types', and 'args' is empty when a FUNCTION_TYPE is passed to this routine (as opposed to a FUNCTION_DECL). This patch fixes this by making the loop iterate over 'types' instead. This patch also moves the retrofitted chain-of-PARM_DECLs printing from here to pp_cxx_requires_expr, the only caller that uses it. Doing so lets us easily output the trailing '...' in the parameter list of a variadic function, which this patch also implements. gcc/cp/ChangeLog: PR c++/98767 * cxx-pretty-print.c (pp_cxx_parameter_declaration_clause): Adjust parameter list loop to iterate over 'types' instead of 'args'. Output the trailing '...' for a variadic function. Remove PARM_DECL support. (pp_cxx_requires_expr): Pretty print the parameter list directly instead of going through pp_cxx_parameter_declaration_clause. gcc/testsuite/ChangeLog: PR c++/98767 * g++.dg/concepts/diagnostic17.C: New test.
2021-04-19c++: ICE with concept defined in function [PR97536]Marek Polacek1-0/+45
This is an ICE-on-invalid, but I keep seeing it when reducing code so I'd like to fix it. We crash on template <typename> void forward() { concept C = true; } which breaks two requirements: [temp.concept]/1: A concept is a template ... [temp.concept]/3: A concept-definition shall inhabit a namespace scope. This patch adds a test that exercises broken code and fixes the ICE by checking that a concept-definition is defined at namespace scope. gcc/cp/ChangeLog: PR c++/97536 * decl.c (grokvardecl): Given an error when a concept is not defined at namespace scope. gcc/testsuite/ChangeLog: PR c++/97536 * g++.dg/concepts/diagnostic16.C: New test.
2021-04-09c++: Fix two issues with auto function parameter [PR99806]Marek Polacek2-0/+28
When we have a member function with auto parameter like this: struct S { void f(auto); }; cp_parser_member_declaration -> grokfield produces a FUNCTION_DECL "void S::foo(auto:1)", and then finish_fully_implicit_template turns that FUNCTION_DECL into a TEMPLATE_DECL. The bug here is that we only call cp_parser_save_default_args for a FUNCTION_DECL. As a consequence, abbrev10.C is rejected because we complain that the default argument has not been defined, and abbrev11.C ICEs, because we don't re-parse the delayed noexcept, so the DEFERRED_PARSE tree leaks into tsubst* where we crash. This patch fixes both issues. gcc/cp/ChangeLog: PR c++/99806 * parser.c (cp_parser_member_declaration): Call cp_parser_save_default_args even for function templates. Use STRIP_TEMPLATE on the declaration we're passing. gcc/testsuite/ChangeLog: PR c++/99806 * g++.dg/concepts/abbrev10.C: New test. * g++.dg/concepts/abbrev11.C: New test.
2021-03-25c++: Fix source_location inconsistency between calls from templates and ↵Jakub Jelinek1-1/+1
non-templates [PR99672] The srcloc19.C testcase shows inconsistency in std::source_location::current() locations between calls from templates and non-templates. The location used by __builtin_source_location comes in both cases from input_location which is set on it by bot_manip when handling the default argument, called during finish_call_expr. The problem is that in templates that input_location comes from the CALL_EXPR we built earlier and that has the combined locus with range between first character of the function name and closing paren with caret on the opening paren, so something printed as caret as: foobar (); ~~~~~~^~ But outside of templates, finish_call_expr is called when input_location is just the closing paren token, i.e. foobar (); ^ and only after that returns we create the combined location and set the CALL_EXPR location to that. So, it means std::source_location::current() reports in templates the column of opening (, while outside of templates closing ). The following patch makes it consistent by creating the combined location already before calling finish_call_expr and temporarily overriding input_location to that. 2021-03-25 Jakub Jelinek <jakub@redhat.com> PR c++/99672 * parser.c (cp_parser_postfix_expression): For calls, create combined_loc and temporarily set input_location to it before calling finish_call_expr. * g++.dg/concepts/diagnostic2.C: Adjust expected caret line. * g++.dg/cpp1y/builtin_location.C (f4, n6): Move #line directives to match locus changes. * g++.dg/cpp2a/srcloc1.C: Adjust expected column numbers. * g++.dg/cpp2a/srcloc2.C: Likewise. * g++.dg/cpp2a/srcloc15.C: Likewise. * g++.dg/cpp2a/srcloc16.C: Likewise. * g++.dg/cpp2a/srcloc19.C: New test. * g++.dg/modules/adhoc-1_b.C: Adjust expected column numbers and caret line. * g++.dg/modules/macloc-1_c.C: Adjust expected column numbers. * g++.dg/modules/macloc-1_d.C: Likewise. * g++.dg/plugin/diagnostic-test-expressions-1.C: Adjust expected caret line. * testsuite/18_support/source_location/consteval.cc (main): Adjust expected column numbers. * testsuite/18_support/source_location/1.cc (main): Likewise.
2021-03-02c++: Fix satisfaction of placeholder type constraints [PR96443]Patrick Palka1-0/+26
This fixes the way we check satisfaction of constraints on placeholder types in various deduction contexts, and in particular when the constraint is dependent. Firstly, when evaluating the return type requirement of a compound requirement, we currently substitute the outer template arguments into the constraint before checking satisfaction. But we should instead be passing in the complete set of template arguments to satisfaction and not do a prior separate substitution. Our current approach leads to us incorrectly rejecting the testcase concepts-return-req2.C below. Secondly, when checking the constraints on a placeholder variable or return type, we don't consider the template arguments of the enclosing context at all. This leads to bogus errors during satisfaction when the constraint is dependent as in the testcase concepts-placeholder3.C below. In order to fix these two issues, we need to be able to normalize the constraints on a placeholder 'auto' on demand, which in turn requires us to know the template parameters that were in scope where the 'auto' was introduced. This information currently doesn't seem to be easily available when we need it, so this patch turns PLACEHOLDER_TYPE_CONSTRAINTS into a TREE_LIST whose TREE_PURPOSE additionally holds the value of current_template_parms whence a constrained 'auto' was formed. This patch also removes some seemingly wrong handling of placeholder type arguments from tsubst_parameter_mapping. The code doesn't trigger with the example used in the comments, because type_uses_auto doesn't look inside non-deduced contexts such as the operand of decltype. And the call to do_auto_deduction seems confused because if 'arg' is a type, then so is 'parm', and therefore 'init' too is a type, but do_auto_deduction expects it to be an expression. Before this patch, this code was dead (as far as our testsuite can tell), but now it breaks other parts of this patch, so let's remove it. gcc/cp/ChangeLog: PR c++/96443 PR c++/96960 * constraint.cc (type_deducible_p): Don't substitute into the constraints, and instead just pass 'args' to do_auto_deduction as the outer template arguments. (tsubst_parameter_mapping): Remove confused code for handling placeholder type arguments. (normalize_placeholder_type_constraint): Define. (satisfy_constraint_expression): Use it to handle placeholder 'auto' types. * cp-tree.h (PLACEHOLDER_TYPE_CONSTRAINTS_INFO): Define. (PLACEHOLDER_TYPE_CONSTRAINTS): Redefine in terms of the above. * pt.c (tsubst) <case TEMPLATE_TYPE_PARM>: Use PLACEHOLDER_TYPE_CONSTRAINTS_INFO instead. (make_constrained_placeholder_type): Set PLACEHOLDER_TYPE_CONSTRAINTS_INFO instead. (do_auto_deduction): Clarify comments about the outer_targs parameter. Rework satisfaction of a placeholder type constraint to pass in the complete set of template arguments directly to constraints_satisfied_p. (splice_late_return_type): Use PLACEHOLDER_TYPE_CONSTRAINTS_INFO instead. Also rebuild the the constraint info on the new auto. gcc/testsuite/ChangeLog: PR c++/96443 PR c++/96960 * g++.dg/concepts/abbrev9.C: New test. * g++.dg/cpp2a/concepts-lambda15.C: New test. * g++.dg/cpp2a/concepts-placeholder3.C: New test. * g++.dg/cpp2a/concepts-return-req2.C: New test. * g++.dg/cpp2a/concepts-ts1.C: Add dg-bogus directive to the call to f15 that we expect to accept.
2021-02-25c++: abbreviated function template return type rewriting [PR98990]Patrick Palka1-0/+22
When an abbreviated function template has a complex placeholder return type such auto& or auto**, the level adjustment performed by splice_late_return_type directly replaces the 'auto' inside the original return type with the level-adjusted 'auto', but that breaks TYPE_CANONICAL caching. Instead, we should rebuild the entire return type using the adjusted 'auto'. This patch makes this happen by tsubsting the original return type with an argument vector that maps the original 'auto' to the adjusted 'auto'. In passing, this patch also reverts the misguided changes to find_type_usage in r10-6571 that made find_type_usage return a tree* instead of a tree so as to discourage this kind of in-place type modification. It occurred to me that the constraint also needs to be rebuilt so that it refers to the adjusted 'auto', but this oversight doesn't seem to cause any issues at the moment due to how do_auto_deduction "manually" substitutes the 'auto' inside the constraint before performing satisfaction. So this'll be fixed later as part of a rework of placeholder type constraint checking. gcc/cp/ChangeLog: PR c++/98990 * pt.c (splice_late_return_type): Rebuild the entire return type if we have to adjust the level of an auto within. (type_uses_auto): Adjust call to find_type_usage. * type-utils.h (find_type_usage): Revert r10-6571 change that made this function return a pointer to the auto node. gcc/testsuite/ChangeLog: PR c++/98990 * g++.dg/concepts/abbrev8.C: New test.
2020-12-05c++: Distinguish unsatisfaction vs errors during satisfaction [PR97093]Patrick Palka1-0/+1
During satisfaction, the flag info.noisy() controls three things: whether to diagnose ill-formed satisfaction (such as the satisfaction value of an atom being non-bool or non-constant); whether to diagnose unsatisfaction; and whether to bypass the satisfaction cache. The flag turns out to be too coarse however, because in some cases we want to diagnose ill-formed satisfaction (and bypass the satisfaction cache) but not diagnose unsatisfaction, for instance when replaying an erroneous satisfaction result from constraint_satisfaction_value, evaluate_concept_check and tsubst_nested_requirement. And when noisily evaluating a disjunction, we want to first evaluate its branches noisily (bypassing the satisfaction cache) but suppress unsatisfaction diagnostics. We currently work around this by instead first evaluating each branch quietly, but that means the recursive calls to satisfy_atom will use the satisfaction cache. To fix this, this patch adds the info.diagnose_unsatisfaction_p() flag, which refines the info.noisy() flag as part of a new sat_info class that derives from subst_info. During satisfaction, info.noisy() now controls whether to diagnose ill-formed satisfaction, and info.diagnose_unsatisfaction_p() controls whether to additionally diagnose unsatisfaction. This enables us to address the above two issues straightforwardly. Incidentally, the change to satisfy_disjunction suppresses the ICE in the PR97093 testcase because we no longer insert atoms into the satisfaction cache that have been incorrectly re-normalized in diagnose_nested_requirement (after losing the necessary template context). But the underlying re-normalization issue remains, and will be fixed in a subsequent patch. gcc/cp/ChangeLog: PR c++/97093 * constraint.cc (struct sat_info): Define. (tsubst_nested_requirement): Pass a sat_info object to satisfy_constraint. (satisfy_constraint_r): Take a sat_info argument instead of subst_info. (satisfy_conjunction): Likewise. (satisfy_disjunction): Likewise. Instead of first evaluating each branch quietly, evaluate each branch only with unsatisfaction diagnostics disabled. Exit early if evaluation of a branch returns error_mark_node. (satisfy_atom): Take a sat_info argument instead of subst_info. Fix a comment. Check diagnose_unsatisfaction_p() instead of noisy() before replaying a substitution failure. (satisfy_constraint): Take a sat_info argument instead of subst_info. (satisfy_associated_constraints): Likewise. (satisfy_constraint_expression): Likewise. (satisfy_declaration_constraints): Likewise. (constraint_satisfaction_value): Likewise and adjust accordingly. Fix formatting. (constraints_satisfied_p): Pass a sat_info object to constraint_satisfaction_value. (evaluate_concept_check): Pass a sat_info object to satisfy_constraint_expression. (diagnose_nested_requirement): Likewise. (diagnose_constraints): Pass an appropriate sat_info object to constraint_satisfaction_value. gcc/testsuite/ChangeLog: PR c++/97093 * g++.dg/concepts/pr94252.C: Verify we no longer issue a spurious unsatisfaction note when diagnosing ill-formed satisfaction. * g++.dg/cpp2a/concepts-requires18.C: No longer expect a spurious unsatisfaction diagnostic when evaluating the nested-requirement subst<void&> of a requires-expression that appears outside of a template. * g++.dg/cpp2a/concepts-requires21.C: Verify we no longer issue a spurious unsatisfaction note when evaluating a nested-requirement of a requires-expression that appears outside of a template. * g++.dg/cpp2a/concepts-nonbool3.C: New test. * g++.dg/cpp2a/concepts-pr97093.C: New test.
2020-11-02c++: Some additional testsNathan Sidwell1-0/+31
I created a few tests on the modules branch that are not actually module-related. Here they are. gcc/testsuite/ * g++.dg/concepts/pack-1.C: New. * g++.dg/lookup/using53.C: Add an enum. * g++.dg/template/error25.C: Relax 'export' error check.
2020-09-22c++: Return only in-scope tparms in keep_template_parm [PR95310]Patrick Palka1-0/+16
In the testcase below, the dependent specializations iter_reference_t<F> and iter_reference_t<Out> share the same tree due to specialization caching. So when find_template_parameters walks through the requires-expression (as part of normalization), it sees and includes the out-of-scope template parameter F in the list of template parameters it found within the requires-expression (along with Out and N). From a correctness perspective this is harmless since the parameter mapping routines only care about the level and index of each parameter, so F is no different from Out in that sense. And it's also harmless that two parameters in the parameter mapping have the same level and index. But having both Out and F in the parameter mapping means extra work for hash_atomic_constrant, tsubst_parameter_mapping and get_mapped_args; and it also means we print this irrelevant template parameter in the testcase's diagnostics (via pp_cxx_parameter_mapping): in requirements with ‘Out o’ [with N = (const int&)&a; F = const int*; Out = const int*] This patch makes keep_template_parm return only in-scope template parameters by looking into ctx_parms for the corresponding in-scope one, through a new helper function corresponding_template_parameter. (That we sometimes print irrelevant template parameters in diagnostics is also the subject of PR99 and PR66968, so the above diagnostic issue could likely be fixed in a more general way, but this targeted fix to keep_template_parm is perhaps worthwhile on its own.) gcc/cp/ChangeLog: PR c++/95310 * pt.c (corresponding_template_parameter): Define. (keep_template_parm): Use it to adjust the given template parameter to the corresponding in-scope one from ctx_parms. gcc/testsuite/ChangeLog: PR c++/95310 * g++.dg/concepts/diagnostic15.C: New test.
2020-09-11c++: Concepts and local externsNathan Sidwell1-0/+39
I discovered that we'd accept constraints on block-scope function decls inside templates. This fixes that. gcc/cp/ * decl.c (grokfndecl): Don't attach to local extern.
2020-08-19c++: Check satisfaction before non-dep convs. [CWG2369]Jason Merrill11-14/+15
It's very hard to use concepts to protect a template from hard errors due to unwanted instantiation if constraints aren't checked until after doing all substitution and checking of non-dependent conversions. It was pretty straightforward to insert the satisfaction check into the logic, but I needed to make the 3-parameter version of satisfy_declaration_constraints call push_tinst_level like the 2-parameter version already does. For simplicity, I also made it add any needed outer template arguments from the TEMPLATE_DECL to the args. The testsuite changes are mostly because this change causes unsatisfaction to cause deduction to fail rather than reject the candidate later in overload resolution. gcc/cp/ChangeLog: DR 2369 * cp-tree.h (push_tinst_level, push_tinst_level_loc): Declare. * constraint.cc (satisfy_declaration_constraints): Use add_outermost_template_args and push_tinst_level. * pt.c (add_outermost_template_args): Handle getting a TEMPLATE_DECL as the first argument. (push_tinst_level, push_tinst_level_loc): No longer static. (fn_type_unification): Check satisfaction before non-dependent conversions. gcc/testsuite/ChangeLog: DR 2369 * g++.dg/concepts/diagnostic10.C: Adjust expexcted errors. * g++.dg/concepts/diagnostic13.C: Adjust expexcted errors. * g++.dg/concepts/diagnostic2.C: Adjust expexcted errors. * g++.dg/concepts/diagnostic3.C: Adjust expexcted errors. * g++.dg/concepts/diagnostic4.C: Adjust expexcted errors. * g++.dg/concepts/diagnostic5.C: Adjust expexcted errors. * g++.dg/concepts/diagnostic9.C: Adjust expexcted errors. * g++.dg/concepts/expression2.C: Adjust expexcted errors. * g++.dg/concepts/fn5.C: Adjust expexcted errors. * g++.dg/concepts/placeholder5.C: Adjust expexcted errors. * g++.dg/concepts/pr67595.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts-pr78752-2.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts-pr84140.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts-recursive-sat3.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts-requires18.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts-requires19.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts3.C: Adjust expexcted errors. * g++.dg/cpp2a/concepts-nondep1.C: New test. * g++.dg/cpp2a/concepts-nondep1a.C: New test.
2020-08-10c++: constraints and address of template-idPatrick Palka1-1/+1
When resolving the address of a template-id, we need to drop functions whose associated constraints are not satisfied, as per [over.over]. We do so in resolve_address_of_overloaded_function, but not in resolve_overloaded_unification or resolve_nondeduced_context, which seems like an oversight. gcc/cp/ChangeLog: * pt.c (resolve_overloaded_unification): Drop functions with unsatisfied constraints. (resolve_nondeduced_context): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-fn5.C: New test. * g++.dg/concepts/fn8.C: Generalize dg-error directive to accept "no matching function ..." diagnostic. * g++.dg/cpp2a/concepts-fn1.C: Likewise. * g++.dg/cpp2a/concepts-ts2.C: Likewise. * g++.dg/cpp2a/concepts-ts3.C: Likewise.
2020-07-29c++: abbreviated function template friend matching [PR96106]Patrick Palka1-0/+14
In the below testcase, duplicate_decls wasn't merging the tsubsted friend declaration for 'void add(auto)' with its definition, because reduce_template_parm_level (during tsubst_friend_function) lost the DECL_VIRTUAL_P flag on the auto's invented template parameter, which caused template_heads_equivalent_p to deem the two template heads as not equivalent in C++20 mode. This patch makes reduce_template_parm_level carry over the DECL_VIRTUAL_P flag from the original TEMPLATE_PARM_DECL. gcc/cp/ChangeLog: PR c++/96106 * pt.c (reduce_template_parm_level): Propagate DECL_VIRTUAL_P from the original TEMPLATE_PARM_DECL to the new lowered one. gcc/testsuite/ChangeLog: PR c++/96106 * g++.dg/concepts/abbrev7.C: New test.
2020-07-07c++: wrong pretty printing of nested type [PR95303]Patrick Palka1-0/+36
In the testcase below, we pretty print the nested type A<int>::B as A<int>::B<int> because we don't check whether B is itself a class template before printing the innermost set of template arguments from B's TEMPLATE_INFO (which in this case belong to A). This patch fixes this by checking PRIMARY_TEMPLATE_P beforehand. gcc/cp/ChangeLog: PR c++/95303 * cxx-pretty-print.c (pp_cxx_unqualified_id): Check PRIMARY_TEMPLATE_P before printing the innermost template arguments. gcc/testsuite/ChangeLog: PR c++/95303 * g++.dg/concepts/diagnostic14.C: New test.
2020-05-29c++: satisfaction value of type typedef to bool [PR95386]Patrick Palka1-0/+11
In the testcase below, the satisfaction value of fn1<int>'s constraint is INTEGER_CST '1' of type BOOLEAN_TYPE value_type, which is a typedef to the standard boolean_type_node. But satisfaction_value expects to see exactly boolean_true_node or integer_one_node, which this value is neither, causing us to trip over the assert therein. This patch changes satisfaction_value to accept INTEGER_CST of any boolean type. gcc/cp/ChangeLog: PR c++/95386 * constraint.cc (satisfaction_value): Accept INTEGER_CST of any boolean type. gcc/testsuite/ChangeLog: PR c++/95386 * g++.dg/concepts/pr95386.C: New test.
2020-05-29c++: P0848R3 and member function templates [PR95181]Patrick Palka2-0/+17
When comparing two special member function templates to see if one hides the other (as per P0848R3), we need to check satisfaction which we can't do on templates. So this patch makes add_method skip the eligibility test on member function templates and just lets them coexist. gcc/cp/ChangeLog: PR c++/95181 * class.c (add_method): Let special member function templates coexist if they are not equivalently constrained, or in a class template. gcc/testsuite/ChangeLog: PR c++/95181 * g++.dg/concepts/pr95181.C: New test. * g++.dg/concepts/pr95181-2.C: New test. Co-authored-by: Jason Merrill <jason@redhat.com>
2020-05-05Merge dg-options and dg-additional-options if len <= 120 chars.Martin Liska1-2/+1
gcc/testsuite/ChangeLog: 2020-04-15 Martin Liska <mliska@suse.cz> * g++.dg/concepts/diagnostic1.C: Merge dg-options and dg-additional-options if len <= 120 chars. * g++.dg/cpp1y/new1.C: Likewise. * g++.dg/cpp1y/new2.C: Likewise. * g++.dg/debug/dwarf2/pr61433.C: Likewise. * g++.dg/init/new18.C: Likewise. * g++.dg/ipa/devirt-19.C: Likewise. * g++.dg/ipa/devirt-52.C: Likewise. * g++.dg/ipa/pr44372.C: Likewise. * g++.dg/ipa/pr58371.C: Likewise. * g++.dg/ipa/pr63587-2.C: Likewise. * g++.dg/ipa/pr78211.C: Likewise. * g++.dg/opt/dump1.C: Likewise. * g++.dg/opt/pr44919.C: Likewise. * g++.dg/opt/pr47615.C: Likewise. * g++.dg/opt/pr82159-2.C: Likewise. * g++.dg/other/pr52048.C: Likewise. * g++.dg/pr57662.C: Likewise. * g++.dg/pr59510.C: Likewise. * g++.dg/pr67989.C: Likewise. * g++.dg/pr81194.C: Likewise. * g++.dg/template/canon-type-8.C: Likewise. * g++.dg/template/crash107.C: Likewise. * g++.dg/template/show-template-tree-3.C: Likewise. * g++.dg/tm/cgraph_edge.C: Likewise. * g++.dg/torture/20141013.C: Likewise. * g++.dg/torture/pr34641.C: Likewise. * g++.dg/torture/pr34850.C: Likewise. * g++.dg/torture/pr36745.C: Likewise. * g++.dg/torture/pr40991.C: Likewise. * g++.dg/torture/pr48271.C: Likewise. * g++.dg/torture/pr53602.C: Likewise. * g++.dg/torture/pr53752.C: Likewise. * g++.dg/torture/pr54838.C: Likewise. * g++.dg/torture/pr58252.C: Likewise. * g++.dg/tree-ssa/pr22444.C: Likewise. * g++.dg/tree-ssa/pr24351-3.C: Likewise. * g++.dg/tree-ssa/pr27283.C: Likewise. * g++.dg/tree-ssa/pr27291.C: Likewise. * g++.dg/tree-ssa/pr27548.C: Likewise. * g++.dg/tree-ssa/pr42337.C: Likewise. * g++.dg/ubsan/pr65583.C: Likewise. * g++.old-deja/g++.robertl/eb27.C: Likewise. * gcc.dg/tree-ssa/dse-points-to.c: Likewise. * gcc.target/arm/simd/vmmla_1.c: Likewise. * gcc.target/i386/vect-pr67800.c: Likewise. * gcc.target/mips/cfgcleanup-jalr2.c: Likewise. * gcc.target/mips/cfgcleanup-jalr3.c: Likewise.
2020-04-30c++ ICE with nested requirement as default tpl parm[PR94827]Nathan Sidwell1-0/+15
Template headers are not incrementally updated as we parse its parameters. We maintain a dummy level until the closing > when we replace the dummy with a real parameter set. requires processing was expecting a properly populated arg_vec in current_template_parms, and then creates a self-mapping of parameters from that. But we don't need to do that, just teach map_arguments to look at TREE_VALUE when args is NULL. * constraint.cc (map_arguments): If ARGS is null, it's a self-mapping of parms. (finish_nested_requirement): Do not pass argified current_template_parms to normalization. (tsubst_nested_requirement): Don't assert no template parms.
2020-04-29c++: Nondeterministic concepts diagnostics [PR94830]Patrick Palka2-1/+15
This patch makes the order in which template parameters appear in the TREE_LIST returned by find_template_parameters deterministic between runs. The current nondeterminism is semantically harmless, but it has the undesirable effect of causing some concepts diagnostics which print a constraint's parameter mapping via pp_cxx_parameter_mapping to also be nondeterministic, as in the testcases below. gcc/cp/ChangeLog: PR c++/94830 * pt.c (find_template_parameter_info::parm_list): New field. (keep_template_parm): Use the new field to build up the parameter list here instead of ... (find_template_parameters): ... here. Return ftpi.parm_list. gcc/testsuite/ChangeLog: PR c++/94830 * g++.dg/concepts/diagnostics12.C: Clarify the dg-message now that the corresponding diagnostic is deterministic. * g++.dg/concepts/diagnostics13.C: New test.
2020-04-28c++: Parameter pack in requires parameter list [PR94808]Patrick Palka2-2/+18
When printing the substituted parameter list of a requires-expression as part of the "in requirements with ..." context line during concepts diagnostics, we weren't considering that substitution into a parameter pack can yield zero or multiple parameters. This patch changes the way we print the parameter list of a requires-expression in print_requires_expression_info. We now print the dependent form of the parameter list (along with its template parameter mapping) instead of printing its substituted form. Besides being an improvement in its own, this also sidesteps the substitution issue in the PR altogether. gcc/cp/ChangeLog: PR c++/94808 * error.c (print_requires_expression_info): Print the dependent form of the parameter list with its template parameter mapping, rather than printing the substituted form. gcc/testsuite/ChangeLog: PR c++/94808 * g++.dg/concepts/diagnostic12.C: New test. * g++.dg/concepts/diagnostic5.C: Adjust dg-message.
2020-04-24c++: add "'requires' only available with ..." notePatrick Palka1-0/+6
This adds a note suggesting to enable concepts whenever 'requires' is parsed as an invalid type name with concepts disabled. gcc/cp/ChangeLog: * parser.c (cp_parser_diagnose_invalid_type_name): Suggest enabling concepts if the invalid identifier is 'requires'. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic11.C: New test.
2020-04-21c++: Diagnose invalid use of member function in requiresPatrick Palka1-0/+18
This updates diagnose_valid_expression to mirror the convert_to_void check added to tsubst_valid_expression_requirement by r10-7554. gcc/cp/ChangeLog: PR c++/67825 * constraint.cc (diagnose_valid_expression): Check convert_to_void here as well as in tsubst_valid_expression_requirement. gcc/testsuite/ChangeLog: PR c++/67825 * g++.dg/concepts/diagnostic10.C: New test. * g++.dg/cpp2a/concepts-pr67178.C: Adjust dg-message.
2020-04-21c++: Constrained inherited constructor template [PR94549]Patrick Palka1-2/+2
A comment in satisfy_declaration_constraints says /* For inherited constructors, consider the original declaration; it has the correct template information attached. */ d = strip_inheriting_ctors (d); but it looks like this comment is wrong when the inherited constructor is for an instantiation of a constructor template. In that case, DECL_TEMPLATE_INFO is correct and DECL_INHERITED_CTOR points to the constructor template of the base class rather than to the particular instantiation of the constructor template (and so the DECL_TI_ARGS of the DECL_INHERITED_CTOR are in their dependent form). So doing strip_inheriting_ctors in this case then eventually leads to satisfy_associated_constraints returning true regardless of the constraints themselves, due to the passed in 'args' being dependent. An inherited constructor seems to have a non-empty DECL_TEMPLATE_INFO only when it's for an instantiation of a constructor template, so this patch fixes this issue by checking for empty DECL_TEMPLATE_INFO before calling strip_inheriting_ctors. There is another unguarded call to strip_inheriting_ctors in get_normalized_constraints_from_decl, but this one seems to be safe to do unconditionally because the rest of that function doesn't need/look at the DECL_TI_ARGS of the decl. gcc/cp/ChangeLog: PR c++/94549 * constraint.cc (satisfy_declaration_constraints): Don't strip the inherited constructor if it already has template information. gcc/testsuite/ChangeLog: PR c++/94549 * g++.dg/concepts/inherit-ctor3.C: Adjust expected diagnostics. * g++.dg/cpp2a/concepts-inherit-ctor4.C: New test. * g++.dg/cpp2a/concepts-inherit-ctor8.C: New test.
2020-04-18c++: Abbreviated function template return type [PR92187]Patrick Palka2-0/+27
When updating an auto return type of an abbreviated function template in splice_late_return_type, we should also propagate PLACEHOLDER_TYPE_CONSTRAINTS (and cv-qualifiers) of the original auto node. gcc/cp/ChangeLog: PR c++/92187 * pt.c (splice_late_return_type): Propagate cv-qualifiers and PLACEHOLDER_TYPE_CONSTRAINTS from the original auto node to the new one. gcc/testsuite/ChangeLog: PR c++/92187 * g++.dg/concepts/abbrev5.C: New test. * g++.dg/concepts/abbrev6.C: New test.
2020-04-14c++: Add testcase for PR c++/93207Patrick Palka1-0/+26
gcc/testsuite/ChangeLog: PR c++/93207 * g++.dg/concepts/variadic5.C: New test.
2020-04-14c++: "'decltype_type' not supported" in diagnostic [PR85278]Patrick Palka1-0/+11
This fixes a garbled concepts diagnostic by moving the handling of DECLTYPE_TYPE from pp_cxx_type_specifier_seq to cxx_pretty_printer::simple_type_specifier, a move which also seems to be more consistent with the language grammar. This patch also fixes pretty printing of rvalue reference types via cxx_pretty_printer::type_id, which eventually calls pp_c_pointer which currently doesn't distinguish between lvalue and rvalue references. gcc/c-family/ChangeLog: PR c++/85278 * c-pretty-print.c (pp_c_pointer) <case REFERENCE_TYPE>: Print a double ampersand if it's an rvalue reference type. gcc/cp/ChangeLog: PR c++/85278 * cxx-pretty-print.c (cxx_pretty_printer:simple_type_specifier) <case DECLTYPE_TYPE>: Handle DECLTYPE_TYPE here instead of ... (pp_cxx_type_specifier_seq) <case DECLTYPE_TYPE>: ... here. (cxx_pretty_printer::direct_abstract_declarator) <case DECLTYPE_TYPE>: New no-op case. gcc/testsuite/ChangeLog: PR c++/85278 * g++.dg/concepts/diagnostic9.C: New test.
2020-03-28c++: Diagnose when "requires" is used instead of "requires requires" [PR94306]Patrick Palka1-0/+6
This adds support to detect and recover from the case where an opening brace immediately follows the start of a requires-clause. So rather than emitting the error error: expected primary-expression before '{' token followed by a slew of irrevelant errors, we now assume the user had intended to write "requires requires {" and diagnose and recover accordingly. gcc/cp/ChangeLog: PR c++/94306 * parser.c (cp_parser_requires_clause_opt): Diagnose and recover from "requires {" when "requires requires {" was probably intended. gcc/testsuite/ChangeLog: PR c++/94306 * g++.dg/concepts/diagnostic8.C: New test.
2020-03-28c++: requires-expression outside of a template is misevaluated [PR94252]Patrick Palka2-0/+38
This PR shows that a REQUIRES_EXPR outside of a template can sometimes be misevaluated. This happens because the evaluation routine tsubst_requires_expr (and diagnose_requires_expr) assumes the REQUIRES_EXPR's subtrees are templated trees and that therefore it's safe to call tsubst_expr on them. But this assumption isn't valid when we've parsed a REQUIRES_EXPR outside of a template context. In order to make this assumption valid here, this patch sets processing_template_decl to non-zero before parsing the body of a REQUIRES_EXPR so that its subtrees are indeed always templated trees. gcc/cp/ChangeLog: PR c++/94252 * constraint.cc (tsubst_compound_requirement): Always suppress errors from type_deducible_p and expression_convertible_p, as they're not substitution errors. (diagnose_atomic_constraint) <case INTEGER_CST>: Remove this case so that we diagnose INTEGER_CST expressions of non-bool type via the default case. * cp-gimplify.c (cp_genericize_r) <case REQUIRES_EXPR>: New case. * parser.c (cp_parser_requires_expression): Always parse the requirement body as if we're processing a template, by temporarily incrementing processing_template_decl. Afterwards, if we're not actually in a template context, perform semantic processing to diagnose any invalid types and expressions. * pt.c (tsubst_copy_and_build) <case REQUIRES_EXPR>: Remove dead code. * semantics.c (finish_static_assert): Explain an assertion failure when the condition is a REQUIRES_EXPR like we do when it is a concept check. gcc/testsuite/ChangeLog: PR c++/94252 * g++.dg/concepts/diagnostic7.C: New test. * g++.dg/concepts/pr94252.C: New test. * g++.dg/cpp2a/concepts-requires18.C: Adjust to expect an additional diagnostic.
2020-03-28c++: Respect current_constraint_diagnosis_depth in diagnose_compound_requirementPatrick Palka2-4/+2
The previous patch tries to avoid changing our current default diagnostics. But for the sake of consistency we arguably should also respect current_constraint_diagnosis_depth in diagnose_compound_requirement() like we do in the other error-replaying diagnostic routines. But doing so would be a change to our default diagnostics behavior, so the change has been split out into this separate patch for separate consideration. gcc/cp/ChangeLog: * constraint.cc (diagnose_compound_requirement): When diagnosing a compound requirement, maybe replay the satisfaction failure, subject to the current diagnosis depth. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic1.C: Pass -fconcepts-diagnostics-depth=2. * g++.dg/concepts/diagnostic5.C: Adjust expected diagnostics. * g++.dg/cpp2a/concepts-iconv1.C: Pass -fconcepts-diagnostics-depth=2. * g++.dg/cpp2a/concepts-requires5.C: Likewise.
2020-03-28c++: Replay errors during diagnosis of constraint satisfaction failuresPatrick Palka2-1/+47
This patch adds a new flag -fconcepts-diagnostics-depth to the C++ frontend which controls how deeply we replay errors when diagnosing a constraint satisfaction failure. The default is -fconcepts-diagnostics-depth=1 which diagnoses only the topmost constraint satisfaction failure and is consistent with our behavior before this patch. By increasing this flag's value, the user can control how deeply they want the compiler to explain a constraint satisfaction error. For example, if the unsatisfied constraint is a disjunction, then the default behavior is to just say "no branch in the disjunction is satisfied", but with -fconcepts-diagnostics-depth=2 we will additionally replay and diagnose the error in each branch of the disjunction. And if the unsatisfied constraint is a requires expression, then we will replay the error in the requires expression, etc. This proceeds recursively until there is nothing more to replay or we exceeded the maximum depth specified by the flag. Implementation wise, this patch essentially just uncomments the existing commented-out code that performs the error-replaying, and along the way adds logic to keep track of and limit the current replay depth. Besides that, there is a new routine collect_operands_of_disjunction which flattens a disjunction and collects all of its operands into a vector. The extra diagnostics enabled by this flag are at times longer than they need to be (e.g. "the operand is_array_v<...> is unsatisfied because \n the expression is_array_v<...> [with ...] evaluated to false") and not immediately easy to follow (especially when there are nested disjunctions), but the transparency provided by these optional diagnostics seems to be pretty helpful in practice. gcc/c-family/ChangeLog: * c.opt: Add -fconcepts-diagnostics-depth. gcc/cp/ChangeLog: * constraint.cc (finish_constraint_binary_op): Set the location of EXPR as well as its range, because build_x_binary_op doesn't always do so. (current_constraint_diagnosis_depth): New. (concepts_diagnostics_max_depth_exceeded_p): New. (collect_operands_of_disjunction): New. (satisfy_disjunction): When diagnosing a satisfaction failure, maybe replay each branch of the disjunction, subject to the current diagnosis depth. (diagnose_valid_expression): When diagnosing a satisfaction failure, maybe replay the substitution error, subject to the current diagnosis recursion. (diagnose_valid_type): Likewise. (diagnose_nested_requiremnet): Likewise. (diagnosing_failed_constraint::diagnosing_failed_constraint): Increment current_constraint_diagnosis_depth when diagnosing. (diagnosing_failed_constraint::~diagnosing_failed_constraint): Decrement current_constraint_diagnosis_depth when diagnosing. (diagnosing_failed_constraint::replay_errors_p): New static member function. (diagnose_constraints): Don't diagnose if concepts_diagnostics_max_depth is 0. Emit a one-off note to increase -fconcepts-diagnostics-depth if the limit was exceeded. * cp-tree.h (diagnosing_failed_constraint::replay_errors_p): Declare. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic2.C: Expect "no operand" instead of "neither operand". * g++.dg/concepts/diagnostic5.C: New test.
2020-03-24c++: Improve handling of ill-formed constraints [PR94186].Jason Merrill1-1/+1
It would have been trivial to make the error for non-bool constraint in satisfy_atom unconditional, but that didn't give context for the error or printing with the dependent form and template arguments. So I changed a couple of places so that, when a hard error is encountered during quiet substitution/satisfaction, we go through again noisily; this builds up the necessary context. The similar change to tsubst_nested_requirement does not build up the necessary context; rather than try to fix that now I changed get_constraint_error_location to give up and use input_location if there's no CONSTR_CONTEXT. In the case of concepts-pr67697.C, we still have a good source location because the NESTED_REQ has a correct EXPR_LOCATION, but this patch doesn't improve context printing for this case as it does for the above. gcc/cp/ChangeLog 2020-03-24 Jason Merrill <jason@redhat.com> PR c++/94186 * constraint.cc (constraint_satisfaction_value): Repeat noisily on error. (tsubst_nested_requirement): Likewise. (get_constraint_error_location): Allow missing context. (diagnose_atomic_constraint): Diagnose non-bool constraint here. (satisfy_atom): Not here. Only diagnose non-constant when noisy.
2020-03-20c++: Include the constraint parameter mapping in diagnostic constraint contextsPatrick Palka1-0/+14
When diagnosing a constraint error, we currently try to print the constraint inside a diagnostic constraint context with its template arguments substituted in. If substitution fails, then we instead just print the dependent form, as in the test case below: .../diagnostic6.C:14:15: error: static assertion failed 14 | static_assert(E<int>); // { dg-error "static assertion failed|not a class" } | ^~~~~~ .../diagnostic6.C:14:15: note: constraints not satisfied .../diagnostic6.C:4:11: required for the satisfaction of ‘C<T>’ .../diagnostic6.C:8:11: required for the satisfaction of ‘D<typename T::type>’ .../diagnostic6.C:14:15: error: ‘int’ is not a class, struct, or union type But printing just the dependent form sometimes makes it difficult to understand the underlying failure. In the above example, for instance, there's no indication of how the template argument 'int' relates to either of the 'T's. This patch improves the situation by changing these diagnostics to always print the dependent form of the constraint, and alongside it the (preferably substituted) constraint parameter mapping. So with the same test case below we now get: .../diagnostic6.C:14:15: error: static assertion failed 14 | static_assert(E<int>); // { dg-error "static assertion failed|not a class" } | ^~~~~~ .../diagnostic6.C:14:15: note: constraints not satisfied .../diagnostic6.C:4:11: required for the satisfaction of ‘C<T>’ [with T = typename T::type] .../diagnostic6.C:8:11: required for the satisfaction of ‘D<typename T::type>’ [with T = int] .../diagnostic6.C:14:15: error: ‘int’ is not a class, struct, or union type This change arguably makes it easier to figure out what's going on whenever a constraint fails due to substitution creating an invalid type rather than failing due to the constraint evaluating to false. gcc/cp/ChangeLog: * cxx-pretty-print.c (pp_cxx_parameter_mapping): Make extern. Move the "[with ]" bits to here from ... (pp_cxx_atomic_constraint): ... here. * cxx-pretty-print.h (pp_cxx_parameter_mapping): Declare. * error.c (rebuild_concept_check): Delete. (print_concept_check_info): Print the dependent form of the constraint and the preferably substituted parameter mapping alongside it. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic6.C: New test.
2020-03-08c++: Fix missing SFINAE when binding a bit-field to a reference (PR 93729)Patrick Palka1-0/+15
We are unconditionally emitting an error here, without first checking complain. gcc/cp/ChangeLog: PR c++/93729 * call.c (convert_like_real): Check complain before emitting an error about binding a bit-field to a reference. gcc/testsuite/ChangeLog: PR c++/93729 * g++.dg/concepts/pr93729.C: New test.
2020-03-08c++: Fix pretty printing of TYPENAME_TYPEsPatrick Palka1-0/+18
I noticed that in some concepts diagnostic messages, we were printing typename types incorrectly, e.g. printing remove_reference_t<T> as typename remove_reference<T>::remove_reference_t instead of typename remove_reference<T>::type. Fix this by printing the TYPENAME_TYPE_FULLNAME instead of the TYPE_NAME in cxx_pretty_printer::simple_type_specifier, which is consistent with how dump_typename in error.c does it. gcc/cp/ChangeLog: * cxx-pretty-print.c (cxx_pretty_printer::simple_type_specifier) [TYPENAME_TYPE]: Print the TYPENAME_TYPE_FULLNAME instead of the TYPE_NAME. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic4.C: New test.
2020-02-27Compare ARGUMENT_PACKS [pr93933]Nathan Sidwell1-0/+31
This implements Jason's suggested approach: 'I'd think that the bug is that we're treating them as types in the first place; they aren't types, so they shouldn't reach comptypes. I'd lean toward adding an assert to that effect and fixing the caller to use e.g. template_args_equal.' PR c++/93933 * pt.c (template_args_equal): Pass ARGUMENT_PACKS through to cp_tree_equal. * tree.c (cp_tree_equal): Compare ARGUMENT_PACKS here, * typeck.c (comptypes): Assert we don't get any argument packs.
2020-02-26c++: Some improvements to concept diagnosticsPatrick Palka2-0/+59
This patch improves our concept diagnostics in two ways. First, it sets a more precise location for the constraint expressions built in finish_constraint_binary_op. As a result, when a disjunction is unsatisfied we now print e.g. .../include/bits/range_access.h:467:2: note: neither operand of the disjunction is satisfied 466 | requires is_bounded_array_v<remove_reference_t<_Tp>> || __member_end<_Tp> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 467 | || __adl_end<_Tp> | ^~~~~~~~~~~~~~~~~ instead of .../include/bits/range_access.h:467:2: note: neither operand of the disjunction is satisfied 467 | || __adl_end<_Tp> | ^~ Second, this patch changes diagnose_atomic_constraint to print unsatisfied atomic constraint expressions with their template arguments. So e.g. we now print cpp2a/concepts-pr67719.C:9:8: note: the expression ‘(... &&(C<Tx>)()) [with Tx = {int, long int, void}]’ evaluated to ‘false’ instead of cpp2a/concepts-pr67719.C:9:8: note: the expression ‘(... &&(C<Tx>)())’ evaluated to ‘false’ Tested on x86_64-pc-linux-gnu, and verified that all the diagnostics emitted in our concept tests are no worse with this patch. gcc/cp/ChangeLog: * constraint.cc (finish_constraint_binary_op): Set expr's location range to the range of its operands. (satisfy_atom): Pass MAP instead of ARGS to diagnose_atomic_constraint. (diagnose_trait_expr): Take the instantiated parameter mapping MAP instead of the corresponding template arguments ARGS and adjust body accordingly. (diagnose_requires_expr): Likewise. (diagnose_atomic_constraint): Likewise. When printing an atomic constraint expression, print the instantiated parameter mapping alongside it. * cxx-pretty-print.cc (cxx_pretty_printer::expression) [NONTYPE_ARGUMENT_PACK]: Print braces around a NONTYPE_ARGUMENT_PACK. (cxx_pretty_printer::type_id): Handle TYPE_ARGUMENT_PACK. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic2.C: New test. * g++.dg/concepts/diagnostic3.C: New test.
2020-02-15c++: Add test for PR 68061.Jason Merrill1-0/+6
PR c++/68061 * g++.dg/concepts/attrib1.C: New.
2020-02-10c++: Fix return type deduction with an abbreviated function templatePatrick Palka1-0/+11
This patch fixes two issues with return type deduction in the presence of an abbreviated function template. The first issue (PR 69448) is that if a placeholder auto return type contains any modifiers such as & or *, then the abbreviated function template compensation in splice_late_return_type does not get performed for the underlying auto node, leading to incorrect return type deduction. This happens because splice_late_return_type does not consider that a placeholder auto return type might have modifiers. To fix this it seems we need to look through modifiers in the return type to obtain the location of the underlying auto node in order to replace it with the adjusted auto node. To that end this patch refactors the utility function find_type_usage to return a pointer to the matched tree, and uses it to find and replace the underlying auto node. The second issue (PR 80471) is that the AUTO_IS_DECLTYPE flag is not being preserved in splice_late_return_type when compensating for an abbreviated function template, leading to us treating a decltype(auto) return type as if it was an auto return type. Fixed by making make_auto_1 set the AUTO_IS_DECLTYPE flag whenever we're building a decltype(auto) node and adjusting callers appropriately. The test for PR 80471 is adjusted to expect the correct behavior. gcc/cp/ChangeLog: PR c++/69448 PR c++/80471 * type-utils.h (find_type_usage): Refactor to take a tree * and to return a tree *, and update documentation accordingly. * pt.c (make_auto_1): Set AUTO_IS_DECLTYPE when building a decltype(auto) node. (make_constrained_decltype_auto): No need to explicitly set AUTO_IS_DECLTYPE anymore. (splice_late_return_type): Use find_type_usage to find and replace a possibly nested auto node instead of using is_auto. Check test for is_auto into an assert when deciding whether to late_return_type. (type_uses_auto): Adjust the call to find_type_usage. * parser.c (cp_parser_decltype): No need to explicitly set AUTO_IS_DECLTYPE anymore. libcc1/ChangeLog: PR c++/69448 PR c++/80471 * libcp1plugin.cc (plugin_get_expr_type): No need to explicitly set AUTO_IS_DECLTYPE anymore. gcc/testsuite/ChangeLog: PR c++/69448 PR c++/80471 * g++.dg/concepts/abbrev3.C: New test. * g++.dg/cpp2a/concepts-pr80471.C: Adjust a static_assert to expect the correct behavior. * g++.dg/cpp0x/auto9.C: Adjust a dg-error directive.
2020-01-23Fix "PR c++/92804 ICE trying to use concept as a nested-name-specifier"Paolo Carlini2-0/+38
A rather simple ICE where we failed to properly check for concept-ids uses in nested-name-specifiers. Tested x86_64-linux. /cp PR c++/92804 * parser.c (cp_parser_nested_name_specifier_opt): Properly diagnose concept-ids. /testsuite PR c++/92804 * g++.dg/concepts/pr92804-1.C: New. * g++.dg/concepts/pr92804-2.C: New.
2020-01-15Fix "PR c++/91073 if constexpr no longer works directly with Concepts."Paolo Carlini2-0/+56
This is a rather serious regression, filed in July 2019. Luckily the fix is simple: is localized to parser.c and cp-tree.h in cp and boils down to only a few lines. Testing OK on x86_64-linux. Approved off-line by Jason Merrill. /cp PR c++/91073 * cp-tree.h (is_constrained_auto): New. * parser.c (cp_parser_maybe_commit_to_declaration): Correctly handle concept-check expressions; take a cp_decl_specifier_seq* instead of a bool. (cp_parser_condition): Update call. (cp_parser_simple_declaration): Likewise. (cp_parser_placeholder_type_specifier): Correctly handle concept-check expressions. /testsuite PR c++/91073 * g++.dg/concepts/pr91073-1.C: New. * g++.dg/concepts/pr91073-2.C: Likewise.
2020-01-14PR c++/92590 - wrong handling of inherited default ctor.Jason Merrill1-2/+2
I thought my earlier fix for 91930 was an obvious bug fix, but apparently an inherited constructor does not count as user-declared. So this patch reverts that change and the other follow-on patches, and fixes 91930 differently, by not letting the inherited default constructor hide the implicitly-declared default constructor. * class.c (add_method): A constrained inherited ctor doesn't hide an implicit derived ctor. Revert: PR c++/91930 - ICE with constrained inherited default ctor. * name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR for inherited constructor. PR c++/92552 - ICE with inherited constrained default ctor. * pt.c (instantiate_class_template_1): Copy TYPE_HAS_USER_CONSTRUCTOR. PR c++/92594 - ICE with inherited trivial default ctor. * method.c (trivial_fn_p): Treat an inherited default constructor like a normal default constructor.
2020-01-13 PR c++/92746 - ICE with noexcept of function concept check.Jason Merrill1-0/+6
Another place that needs to specially handle Concepts TS function-style concepts. * except.c (check_noexcept_r): Handle concept-check.
2020-01-06PR c++/92552 - ICE with inherited constrained default ctor.Jason Merrill1-2/+2
We set TYPE_HAS_USER_CONSTRUCTOR on the template type in lookup_using_decl, but we didn't copy it to the instantiation. Setting it in one_inherited_ctor is too late, as that gets called after we decide whether to set CLASSTYPE_LAZY_DEFAULT_CTOR. This change affects other testcases as well; the changes are fixes for the other inherited constructor tests as well. * pt.c (instantiate_class_template_1): Copy TYPE_HAS_USER_CONSTRUCTOR. * class.c (one_inherited_ctor): Don't set it here. From-SVN: r279936
2019-11-27Diagnose certain constraint errors as hard errors, but otherwise treat them ↵Andrew Sutton1-1/+1
the same as normal SFINAE-type errors. 2019-11-27 Andrew Sutton <asutton@lock3software.com> Diagnose certain constraint errors as hard errors, but otherwise treat them the same as normal SFINAE-type errors. Also, generally clean up the satisfaction functions. gcc/cp/ * constexpr.c (cxx_eval_constant_expression): Use evaluate_concept_check. * constraint.cc (normalize_concept_definition): Accept a diagnostic flag and only cache when not diagnosing errors. (decl_satisfied_cache): Map to trees instead of bools. (satisfy_atom): Guarantee a location for the errors, propagate complain flags to force_rvalue, and emit errors for non-boolean constraints. (get_normalized_constraints_and_args): New overloads. Factored out of satisfy_constraint_expression and satisfy_declaration_constraints. (satisfy_constraint_expression): Propagate diagnostic info to normalization. (satisfy_declaration_constraints): New. Factored out of constraints_satisfied_p. (constraint_satisfaction_value): New. Calls satisfy_constraint_expression or satisfy_declaration_constraints. (constraints_satisfied_p): Call constraint_satisfaction_value. (evaluate_concept_check): Don't take tsubst_falgs_t. Replay satisfaction if an error is encountered. (current_failed_constraint): Moved from pt.c. (diagnose_constraints): Call constraint_satisfaction_value. * cp-tree.h: Update declarations. * pt.c (current_failed_constraint): Moved to constraint.cc. * semantics.c (finish_id_expression_1): Remove a duplicate case. gcc/testsuite/ * g++.dg/concepts/pr84330.C: Update diagnostics. * g++.dg/cpp2a/concepts-requires2.C: Likewise. From-SVN: r278768