OK.

On Tue, Feb 19, 2019 at 1:16 AM Paolo Carlini <paolo.carl...@oracle.com> wrote:
>
> Hi,
>
> On 19/02/19 02:39, Jason Merrill wrote:
> > On 2/18/19 3:15 PM, Paolo Carlini wrote:
> >> Hi,
> >>
> >> On 19/02/19 00:52, Jason Merrill wrote:
> >>> On 2/18/19 12:14 PM, Paolo Carlini wrote:
> >>>> Hi Jason,
> >>>>
> >>>> On 18/02/19 19:28, Jason Merrill wrote:
> >>>>> On 2/18/19 5:31 AM, Paolo Carlini wrote:
> >>>>>> Hi Jason,
> >>>>>>
> >>>>>> On 18/02/19 10:20, Jason Merrill wrote:
> >>>>>>> On 2/17/19 6:58 AM, Paolo Carlini wrote:
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> here, when we don't see an initializer we believe we are surely
> >>>>>>>> dealing with a case of C++17 template argument deduction for
> >>>>>>>> class templates, but, in fact, it's just an ill-formed C++14
> >>>>>>>> template variable specialization. Conveniently, we can use here
> >>>>>>>> too the predicate variable_template_specialization_p. Not 100%
> >>>>>>>> sure about the exact wording of the error message, I added '#'
> >>>>>>>> to %qD to explicitly print the auto-using type too.
> >>>>>>>
> >>>>>>> I guess we should change the assert to a test, so that we give
> >>>>>>> the error if we aren't dealing with a class template
> >>>>>>> placeholder. Variable templates don't seem to be important to
> >>>>>>> test for.
> >>>>>> Thanks, simpler patch.
> >>>>>>> This error is also pretty poor for this testcase, where there is
> >>>>>>> an initializer.
> >>>>>>
> >>>>>> Well, implementation-wise, certainly init == NULL_TREE and only
> >>>>>> when we have an empty pack this specific issue occurs.
> >>>>>>
> >>>>>> In practice, clang simply talks about an empty initializer
> >>>>>> (during instantiation, etc, like we do), whereas EDG explicitly
> >>>>>> says that pack expansion produces an empty list of expressions. I
> >>>>>> don't think that in cp_finish_decl it would be easy for us to do
> >>>>>> exactly the same, we simply see a NULL_TREE as second argument.
> >>>>>> Or we could just *assume* that we are dealing with the outcome of
> >>>>>> a pack expansion, say something like EDG even if we don't have
> >>>>>> details beyond the fact that init == NULL_TREE. I believe that
> >>>>>> without a variadic template the problem cannot occur, because we
> >>>>>> catch the empty initializer much earlier, in grokdeclarator -
> >>>>>> indeed using a !CLASS_PLACEHOLDER_TEMPLATE (auto_node) check.
> >>>>>> What do you think? Again "instantiated for an empty pack" or
> >>>>>> something similar?
> >>>>>
> >>>>> Perhaps we could complain in the code for empty pack expansion
> >>>>> handling in tsubst_init?
> >>>>
> >>>> Ah, thanks Jason. In fact, however, tsubst_init isn't currently
> >>>> involved at all, because, at the end of
> >>>> regenerate_decl_from_template we call by hand tsubst_expr and
> >>>> assign the result to DECL_INITIAL. Simply changing that avoids the
> >>>> ICE. However, the error we issue - likewise for the existing
> >>>> cpp0x/auto31.C - is the rather user-unfriendly
> >>>> "value-initialization of incomplete type ‘auto’", as produced by
> >>>> build_value_init. Thus a simple additional test along the lines
> >>>> already discussed, which now becomes much more simple to implement
> >>>> in a precise way. Again, wording only tentative. I'm also a little
> >>>> puzzled that, otherwise, we could get away with tubst_expr instead
> >>>> of tsubst_init...
> >>>
> >>>> +      if (type_uses_auto (TREE_TYPE (decl)))
> >>>> +    {
> >>>> +      if (complain & tf_error)
> >>>> +        error ("initializer for %q#D expands to an empty list "
> >>>> +           "of expressions", decl);
> >>>> +      return error_mark_node;
> >>>> +    }
> >>>
> >>> This needs to allow the CLASS_PLACEHOLDER_TEMPLATE case.
> >>>
> >>> And yes, we mustn't call build_value_init for a dependent type; if
> >>> the type is dependent, we should just return the NULL_TREE.
> >>
> >> Good. Then I'm finishing testing the below (currently in libstdc++).
> >
> >> +      if (tree auto_node = type_uses_auto (type))
> >> +    if (!CLASS_PLACEHOLDER_TEMPLATE (auto_node))
> >> +      {
> >> +        if (complain & tf_error)
> >> +          error ("initializer for %q#D expands to an empty list "
> >> +             "of expressions", decl);
> >> +        return error_mark_node;
> >> +      }
> >> +
> >> +      if (!dependent_type_p (type))
> >
> > This should probably be 'else if', since we can have auto outside of a
> > template and dependent_type_p will always return false outside of a
> > template.
>
> Ok... Note that the CLASS_PLACEHOLDER_TEMPLATE (auto_node) check in
> tsubst_init doesn't really make a difference for our testsuite and I
> have yet to find a testcase where it does. In cp_finish_decl it did, for
> sure.
>
> That said, if I understand correctly, you mean that in principle when we
> have an 'auto' outside of a template and CLASS_PLACEHOLDER_TEMPLATE is
> true, we don't want to do the build_value_init bits - which we would
> certainly do because dependent_type_p is false. If we are on the same
> page on this, the below regtested successfully.
>
> Thanks! Paolo.
>
> //////////////////////
>

Reply via email to