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