From 5d090b8963547610166689fd06c46e90041a2886 Mon Sep 17 00:00:00 2001 From: asutton Date: Fri, 8 May 2015 17:13:51 +0000 Subject: [PATCH] 2015-05-08 Andrew Sutton Addressing review comments. * gcc/cp/call.c (build_new_function_call): Don't check for template parameters when we're not processing a template decl. * gcc/cp/constraint.cc (function_concept_check_p): Use get_first_fn. (satisfy_expression_constraint): Move sentinel into cp-tree.h. * gcc/cp/parser.c (cp_parser_declarator): Use function_declarator_p. * gcc/cp/cp-tree.h (struct deferring_access_check_sentinel): Moved from constraint.cc. * gcc/cp/semantics: (finish_call_expr) Don't remove constraints. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/c++-concepts@222917 138bc75d-0d04-0410-961f-82ee72b054a4 --- ChangeLog.concepts | 13 +++++++++++++ gcc/cp/call.c | 3 +-- gcc/cp/constraint.cc | 30 +++++++++++++----------------- gcc/cp/cp-tree.h | 21 +++++++++++++++++++-- gcc/cp/parser.c | 22 ++++------------------ gcc/cp/semantics.c | 2 -- 6 files changed, 50 insertions(+), 41 deletions(-) diff --git a/ChangeLog.concepts b/ChangeLog.concepts index 50e2e55b435..f5f3f62ce7f 100644 --- a/ChangeLog.concepts +++ b/ChangeLog.concepts @@ -1,5 +1,18 @@ 2015-05-08 Andrew Sutton + Addressing review comments. + * gcc/cp/call.c (build_new_function_call): Don't check for + template parameters when we're not processing a template decl. + * gcc/cp/constraint.cc (function_concept_check_p): Use + get_first_fn. + (satisfy_expression_constraint): Move sentinel into cp-tree.h. + * gcc/cp/parser.c (cp_parser_declarator): Use function_declarator_p. + * gcc/cp/cp-tree.h (struct deferring_access_check_sentinel): Moved + from constraint.cc. + * gcc/cp/semantics: (finish_call_expr) Don't remove constraints. + +2015-05-08 Andrew Sutton + Use the substituted type, not the deduced arguments, to check placeholder constraints. * gcc/cp/pt.c (do_auto_deduction): Check constraints using diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 617b8d0c32a..b581a5ac5ab 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4158,8 +4158,7 @@ build_new_function_call (tree fn, vec **args, bool koenig_p, tree tmpl = DECL_TI_TEMPLATE (cand->fn); tree targs = DECL_TI_ARGS (cand->fn); tree decl = DECL_TEMPLATE_RESULT (tmpl); - if (DECL_DECLARED_CONCEPT_P (decl) - && !uses_template_parms (targs)) + if (DECL_DECLARED_CONCEPT_P (decl)) return evaluate_function_concept (decl, targs); } diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index f221a80cec2..37cc7abecc8 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -117,7 +117,7 @@ function_concept_check_p (tree t) if (TREE_CODE (fn) == TEMPLATE_ID_EXPR && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD) { - tree f1 = OVL_FUNCTION (TREE_OPERAND (fn, 0)); + tree f1 = get_first_fn (fn); if (TREE_CODE (f1) == TEMPLATE_DECL && DECL_DECLARED_CONCEPT_P (DECL_TEMPLATE_RESULT (f1))) return true; @@ -348,6 +348,12 @@ namespace { Lifting of concept definitions ---------------------------------------------------------------------------*/ +/* Part of constraint normalization. Whenever we find a reference to + a variable concept or a call to a function concept, we lift or + inline that concept's definition into the constraint. This ensures + that constraints are always checked in the immediate instantiation + context. */ + tree lift_expression (tree); /* If the tree T has operands, then lift any concepts out of them. */ @@ -569,9 +575,12 @@ lift_expression (tree t) } /*--------------------------------------------------------------------------- - Constraint normalization + Transformation of expressions into constraints ---------------------------------------------------------------------------*/ +/* Part of constraint normalization. The following functions rewrite + expressions as constraints. */ + tree transform_expression (tree); /* Check that the logical-or or logical-and expression does @@ -1779,20 +1788,7 @@ satisfy_expression_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl) { cp_unevaluated guard; - - /* A sentinel class that ensures that deferred access checks - are popped before a function returns. */ - struct deferring_access_check_sentinel - { - deferring_access_check_sentinel () - { - push_deferring_access_checks (dk_deferred); - } - ~ deferring_access_check_sentinel () - { - pop_deferring_access_checks (); - } - } deferring; + deferring_access_check_sentinel deferring; tree expr = EXPR_CONSTR_EXPR (t); tree check = tsubst_expr (expr, args, complain, in_decl, false); @@ -1834,7 +1830,7 @@ satisfy_implicit_conversion_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl) { /* Don't tsubst as if we're processing a template. If we try - to we can end up generating template-like expresssions + to we can end up generating template-like expressions (e.g., modop-exprs) that aren't properly typed. */ int saved_template_decl = processing_template_decl; processing_template_decl = 0; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 67abc1f02ce..5b45c70c7aa 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4634,8 +4634,9 @@ extern int comparing_specializations; extern int cp_unevaluated_operand; -// An RAII class used to inhibit the evaluation of operands during parsing -// and template instantiation. Evaluation warnings are also inhibited. +/* RAII class used to inhibit the evaluation of operands during parsing + and template instantiation. Evaluation warnings are also inhibited. */ + class cp_unevaluated { public: @@ -6073,6 +6074,22 @@ extern bool perform_access_checks (vec *, extern bool perform_deferred_access_checks (tsubst_flags_t); extern bool perform_or_defer_access_check (tree, tree, tree, tsubst_flags_t); + +/* RAII sentinel to ensures that deferred access checks are popped before + a function returns. */ + +struct deferring_access_check_sentinel +{ + deferring_access_check_sentinel () + { + push_deferring_access_checks (dk_deferred); + } + ~deferring_access_check_sentinel () + { + pop_deferring_access_checks (); + } +}; + extern int stmts_are_full_exprs_p (void); extern void init_cp_semantics (void); extern tree do_poplevel (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c668db4aba2..2cfb9bda202 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18107,24 +18107,10 @@ cp_parser_declarator (cp_parser* parser, declaration and not the abstract declarator. */ if (flag_concepts && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) { - /* We could have things like *f(args) or &f(args). - Look inside references and pointers. */ - cp_declarator* p = declarator; - if (p->kind == cdk_reference || p->kind == cdk_pointer) - p = p->declarator; - - /* Pointers or references with no name, or functions - with no name cannot have constraints. */ - if (!p || !p->declarator) - return declarator; - - /* Look for f(args) but not (*f)(args). */ - if (p && p->kind == cdk_function && p->declarator->kind == cdk_id) - { - declarator->u.function.requires_clause - = cp_parser_trailing_requires_clause (parser, declarator); - } - } + if (function_declarator_p (declarator)) + declarator->u.function.requires_clause + = cp_parser_trailing_requires_clause (parser, declarator); + } return declarator; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 14c677838bc..2de1a56b4b6 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2454,8 +2454,6 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, else { next = OVL_CHAIN (fn); - if (flag_concepts) - remove_constraints (OVL_FUNCTION (fn)); ggc_free (fn); } } -- 2.11.4.GIT