public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
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

             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).