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