On Wed, Oct 3, 2018 at 7:11 PM Marek Polacek <pola...@redhat.com> wrote:
>
> On Wed, Oct 03, 2018 at 10:24:52AM -0400, Jason Merrill wrote:
> > On Tue, Oct 2, 2018 at 5:25 PM Marek Polacek <pola...@redhat.com> wrote:
> > >
> > > On Mon, Oct 01, 2018 at 07:47:10PM -0400, Jason Merrill wrote:
> > > > On Mon, Oct 1, 2018 at 6:41 PM Marek Polacek <pola...@redhat.com> wrote:
> > > > >
> > > > > This patch implements C++20 explicit(bool), as described in:
> > > > > <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0892r2.html>.
> > > > >
> > > > > I tried to follow the noexcept specifier implementation where I 
> > > > > could, which
> > > > > made the non-template parts of this fairly easy.  To make 
> > > > > explicit(expr) work
> > > > > with dependent expressions, I had to add DECL_EXPLICIT_SPEC to 
> > > > > lang_decl_fn,
> > > > > which serves as a vessel to get the explicit-specifier to 
> > > > > tsubst_function_decl
> > > > > where I substitute the dependent arguments.
> > > >
> > > > What's the impact of that on memory consumption?  I'm nervous about
> > > > adding another word to most functions when it's not useful to most of
> > > > them.  For several similar things we've been using hash tables on the
> > > > side.
> > >
> > > Yeah, that is a fair concern.  I'm not sure if I know of a good way to 
> > > measure
> > > it.  I took wide-int.ii and ran /usr/bin/time -v ./cc1plus; then it's 
> > > roughly
> > > Maximum resident set size (kbytes): 95020
> > > vs.
> > > Maximum resident set size (kbytes): 95272
> > > which doesn't seem too bad but I don't know if it proves anything.
> > >
> > > If we went with the hash table, would it work like this?
> > > 1) have a hash table mapping decls (key) to explicit-specifiers
> > > 2) instead of setting DECL_EXPLICIT_SPEC put the parsed explicit-specifier
> > >    into the table
> > > 3) in tsubst_function_decl look if the fn decl is associated with any
> > >    explicit-specifier, if it is, substitute it, and set 
> > > DECL_NONCONVERTING_P
> > >    accordingly.
> >
> > Yes.  I think you want to use tree_cache_map so you don't have to
> > worry about removing entries from the table if the decl is GC'd.
>
> Done (along with the bit idea).

It occurs to me that it might be better to put all these sorts of
things in DECL_ATTRIBUTES instead, but that's definitely a question
for another day.

> +       /* [dcl.fct.spec]
> +          "the constant-expression, if supplied, shall be a contextually
> +          converted constant expression of type bool."  */
> +       expr = build_explicit_specifier (expr, tf_warning_or_error);
> +       /* We could evaluate it -- mark the decl as appropriate.  */
> +       if (expr == boolean_true_node)
> +         set_and_check_decl_spec_loc (decl_specs, ds_explicit, token);
> +       else if (explicit_specifier)
> +         /* The expression was value-dependent.  Remember it so that we can
> +            substitute it later.  */
> +         *explicit_specifier = expr;

What if expr == boolean_false_node?

> +      /* Handle explicit(dependent-expr).  */
> +      if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
> +       {
> +         tree spec = lookup_explicit_specifier (t);
> +         spec = tsubst_copy_and_build (spec, args, complain, in_decl,
> +                                       /*function_p=*/false,
> +                                       /*i_c_e_p=*/true);
> +         spec = build_explicit_specifier (spec, complain);
> +         DECL_NONCONVERTING_P (t) = (spec == boolean_true_node);
> +       }

What if spec is still dependent, e.g. after partial substitution of a
member template?

Jason

Reply via email to