From: Jason Merrill <jason@redhat.com>
To: Andrew Sutton <andrew.n.sutton@gmail.com>
Cc: gcc-patches List <gcc-patches@gcc.gnu.org>,
Braden Obrzut <admin@maniacsvault.net>
Subject: [c++-concepts] code review
Date: Fri, 01 May 2015 18:32:00 -0000 [thread overview]
Message-ID: <5543C6CD.7020403@redhat.com> (raw)
It looks like things are coming together pretty well. What's your
feeling about readiness to merge into the trunk? Is the branch down to
no regressions?
See you on Monday!
> @@ -4146,21 +4146,21 @@ build_new_function_call (tree fn, vec<tree, va_gc> **args, bool koenig_p,
> if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
> {
> /* If overload resolution selects a specialization of a
> + function concept for non-dependent template arguments,
> + the expression is true if the constraints are satisfied
> + and false otherwise.
>
> NOTE: This is an extension of Concepts Lite TS that
> allows constraints to be used in expressions. */
> + if (flag_concepts && !processing_template_decl)
> {
> 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)) {
> + return evaluate_function_concept (decl, targs);
If processing_template_decl is false, uses_template_parms should always
be false as well.
> +function_concept_check_p (tree t)
> + tree fn = CALL_EXPR_FN (t);
> + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR
> + && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD)
> + {
> + tree f1 = OVL_FUNCTION (TREE_OPERAND (fn, 0));
I think you want get_first_fn here.
> if (TEMPLATE_PARM_CONSTRAINTS (current_template_parms))
> - TYPE_CANONICAL (type) = type;
> + SET_TYPE_STRUCTURAL_EQUALITY (type);
This seems like papering over an underlying issue. What was the
testcase that motivated this change?
> @@ -11854,7 +11854,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
> - if (!spec)
> + if (!spec && DECL_LANG_SPECIFIC (t))
> - if (!local_p)
> + if (!local_p && DECL_LANG_SPECIFIC (r))
What motivated these changes? From the testcase, it seems that you're
getting here with the decl for "using TD = int", which shouldn't happen.
> @@ -1159,7 +1159,6 @@ check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
> - tree type = TREE_TYPE (TREE_TYPE (fn));
> - if (!TYPE_NOTHROW_P (type))
> + if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
The old code was incorrectly assuming that CALL_EXPR_FN is always a
function pointer, but your new code seems to be incorrectly assuming
that it's always a function or an expression taking the address of a
function; I think this will break on a call to a function pointer variable.
> @@ -3481,13 +3481,27 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
> case REQUIRES_EXPR:
> + if (!processing_template_decl)
> + return evaluate_constraint_expression (t, NULL_TREE);
> + else
> + *non_constant_p = true;
> + return t;
We shouldn't get here with a dependent REQUIRES_EXPR (or any dependent
expression), so we shouldn't ever hit the else clause.
> @@ -18063,18 +18063,41 @@ cp_parser_declarator (cp_parser* parser,
> + /* Function declarations may be followed by a trailing
> + requires-clause. Declarators for function declartions
> + are function declarators wrapping an id-declarator.
> + If the inner declarator is anything else, it does not
> + declare a function. These may also be reference or
> + pointer declarators enclosing such a function declarator.
> + In the declaration :
> +
> + int *f(args)
> +
> + the declarator is *f(args).
> +
> + Abstract declarators cannot have a requires-clauses
> + because they do not declare functions. Here:
>
> void f() -> int& requires false
>
> + The trailing return type contains an abstract declarator,
> + and the requires-clause applies to the function
> + 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)
I think you can use function_declarator_p here.
> +static inline bool
> +pending_expansion_p (tree t)
> +{
> + return (TREE_CODE (t) == PARM_DECL && CONSTRAINT_VAR_P (t)
> + && PACK_EXPANSION_P (TREE_TYPE (t)));
> +}
What's the difference between this and function_parameter_pack_p?
> + /* 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 ();
> + }
> + }
Let's put this with the other RAII sentinels in cp-tree.h.
> + Lifting of concept definitions
Could we have a bit more description of what "lifting" means here?
> +/*---------------------------------------------------------------------------
> + Constraint normalization
> +---------------------------------------------------------------------------*/
You have two of these headers; I guess the first one should be
"transformation" and could use more description. On the second, I would
retain the old comment
> -// Normalize a template requirement to a logical formula written in terms of
> -// atomic propositions, returing the new expression. If the expression cannot
> -// be normalized, a NULL_TREE is returned.
> +check_implicit_conversion_constraint (tree t, tree args,
> + tsubst_flags_t complain, tree in_decl)
> +{
> + tree expr = ICONV_CONSTR_EXPR (t);
> +
> + /* Don't tsubst as if we're processing a template. If we try
> + 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;
Why are we checking constraints when processing_template_decl is true?
> + Note that this is the only place that we instantiate the
> + constraints. */
> +bool
> +check_constraints (tree ci, tree args)
Except for tsubst_constraint?
> + ++processing_template_decl;
> + tree constr = transform_expression (lift_function_definition (fn, args));
> + --processing_template_decl;
Why do you need to set processing_template_decl here and in other calls
to transform_expression? I don't notice anything that would be helped,
especially now that you're using separate tree codes for constraints,
though there is this in check_logical_expr:
> + /* Resolve the logical operator. Note that template processing is
> + disabled so we get the actual call or target expression back.
> + not_processing_template_sentinel sentinel.
I guess that isn't needed anymore?
> + FIXME: This is defined in pt.c because it's garbage collection
> + code is not being generated for constraint.cc. */
> +static GTY (()) hash_table<constr_hasher> *decl_constraints;
I think you need to add constraint.cc to the gtfiles variable in
cp/config-lang.in. It also looks like the GTFILES_H rule in
gcc/Makefile.in assumes that all sources have the .c extension, so that
may need adjustment.
> @@ -2454,6 +2454,8 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool d
> next = OVL_CHAIN (fn);
> + if (flag_concepts)
> + remove_constraints (OVL_FUNCTION (fn));
I don't think we want to remove constraints here; this code is just
discarding the OVERLOAD node, not the FUNCTION_DECL.
Jason
next reply other threads:[~2015-05-01 18:32 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-01 18:32 Jason Merrill [this message]
2015-05-01 19:21 ` Andrew Sutton
2015-05-08 20:08 ` Andrew Sutton
-- strict thread matches above, loose matches on Subject: below --
2013-02-28 14:07 [c++-concepts] Reserving new keywords for concepts Andrew Sutton
2013-02-28 14:51 ` Gabriel Dos Reis
2013-06-06 15:55 ` [c++-concepts] code review Jason Merrill
2013-06-06 17:48 ` Andrew Sutton
2013-06-06 20:29 ` Jason Merrill
2013-06-08 13:35 ` Andrew Sutton
2013-06-10 0:49 ` Gabriel Dos Reis
2013-06-10 16:27 ` Jason Merrill
2013-06-10 19:30 ` Jason Merrill
2013-06-11 13:45 ` Andrew Sutton
2013-06-11 14:27 ` Jason Merrill
2013-06-11 14:49 ` Andrew Sutton
2013-06-11 15:00 ` Jason Merrill
2013-06-11 15:09 ` Andrew Sutton
2013-06-11 17:54 ` Jason Merrill
2013-06-12 15:53 ` Gabriel Dos Reis
2013-06-12 16:35 ` Jason Merrill
2013-06-14 15:32 ` Andrew Sutton
2013-06-15 1:40 ` Jason Merrill
2013-06-15 2:13 ` Gabriel Dos Reis
2013-06-17 18:11 ` Andrew Sutton
2013-06-17 19:20 ` Jason Merrill
2013-06-18 0:29 ` Gabriel Dos Reis
2013-06-18 16:28 ` Andrew Sutton
2013-06-19 14:21 ` Jason Merrill
2013-06-19 16:10 ` Andrew Sutton
2013-06-20 5:30 ` Gabriel Dos Reis
2013-06-20 13:01 ` Jason Merrill
2013-06-20 13:09 ` Gabriel Dos Reis
2013-06-20 13:19 ` Andrew Sutton
2013-06-20 13:57 ` Jason Merrill
2013-06-20 14:18 ` Andrew Sutton
2013-06-20 15:17 ` Jason Merrill
2013-06-20 15:22 ` Gabriel Dos Reis
2013-06-20 15:27 ` Jason Merrill
2013-06-20 15:29 ` Gabriel Dos Reis
2013-06-20 15:50 ` Andrew Sutton
2013-06-20 17:23 ` Jason Merrill
2013-06-20 18:33 ` Jason Merrill
2013-06-21 12:46 ` Andrew Sutton
2013-06-24 15:55 ` Jason Merrill
2013-06-20 15:20 ` Gabriel Dos Reis
2013-06-09 20:34 ` Oleg Endo
2013-06-10 0:34 ` Gabriel Dos Reis
2013-06-10 14:51 ` Diego Novillo
2013-06-10 22:51 ` Lawrence Crowl
2013-06-10 16:14 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5543C6CD.7020403@redhat.com \
--to=jason@redhat.com \
--cc=admin@maniacsvault.net \
--cc=andrew.n.sutton@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).