Message ID | 53BD01BE.5030808@oracle.com |
---|---|
State | New |
Headers | show |
OK. Jason
.. unfortunately something is wrong with this commit, thus c++/62072. For the time being I'm simply reverting it and adding the new testcase. By the way, more generally, I don't understand at the moment how we can safely use complete_type in the middle of tsubst & co: it can emit hard errors about, eg, incompleteness (see c++/62072) irrespective of the tsubst_flags_t argument... Thanks, Paolo.
On 08/15/2014 12:17 PM, Paolo Carlini wrote: > By the way, more generally, I don't understand at the moment how we can > safely use complete_type in the middle of tsubst & co: it can emit hard > errors about, eg, incompleteness (see c++/62072) irrespective of the > tsubst_flags_t argument... Yes, it can, that's part of the language; remember "Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure", invalid constructs outside that context result in hard errors. Jason
Hi, On 08/15/2014 07:30 PM, Jason Merrill wrote: > On 08/15/2014 12:17 PM, Paolo Carlini wrote: >> By the way, more generally, I don't understand at the moment how we can >> safely use complete_type in the middle of tsubst & co: it can emit hard >> errors about, eg, incompleteness (see c++/62072) irrespective of the >> tsubst_flags_t argument... > Yes, it can, that's part of the language; remember "Only invalid types > and expressions in the immediate context of the function type and its > template parameter types can result in a deduction failure", invalid > constructs outside that context result in hard errors. I see, it boils down again to that "famous" wording... Now, is it possible that the issue we are facing with implementing DR 1584 has to do with the fact that our unify doesn't tell template functions vs template classes?!? Thus we should return 1 from check_cv_quals_for_unify when arg is a FUNCTION_TYPE *and* DECL_TYPE_TEMPLATE_P (TREE_TYPE (tparms)) is true?!? (we could pass the information in a flag) Because I don't think an equivalent of the key bits of c++/62072: template<typename T> struct tuple_size { }; template<typename T> struct tuple_size<const T> : tuple_size<T> { }; can be constructed for template functions?!? Paolo.
Index: cp/pt.c =================================================================== --- cp/pt.c (revision 212385) +++ cp/pt.c (working copy) @@ -17189,6 +17189,11 @@ check_cv_quals_for_unify (int strict, tree arg, tr int arg_quals = cp_type_quals (arg); int parm_quals = cp_type_quals (parm); + /* DR 1584: cv-qualification of a deduced function type is + ignored; see 8.3.5 [dcl.fct]. */ + if (TREE_CODE (arg) == FUNCTION_TYPE) + return 1; + if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM && !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL)) { Index: testsuite/g++.dg/cpp0x/pr57466.C =================================================================== --- testsuite/g++.dg/cpp0x/pr57466.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr57466.C (working copy) @@ -0,0 +1,18 @@ +// PR c++/57466 +// { dg-do compile { target c++11 } } + +template<typename T> + constexpr bool + is_pointer(const T*) + { return true; } + +template<typename T> + constexpr bool + is_pointer(const T&) + { return false; } + +using F = void(); + +constexpr F* f = nullptr; + +static_assert( is_pointer(f), "function pointer is a pointer" ); Index: testsuite/g++.dg/template/pr57466.C =================================================================== --- testsuite/g++.dg/template/pr57466.C (revision 0) +++ testsuite/g++.dg/template/pr57466.C (working copy) @@ -0,0 +1,8 @@ +// DR 1584, PR c++/57466 + +template<class T> void f2(const T*); +void g2(); + +void m() { + f2(g2); // OK: cv-qualification of deduced function type ignored +} Index: testsuite/g++.dg/template/unify6.C =================================================================== --- testsuite/g++.dg/template/unify6.C (revision 212385) +++ testsuite/g++.dg/template/unify6.C (working copy) @@ -3,21 +3,20 @@ void Baz (); -template <typename T> void Foo1 (T *); // #1 -template <typename T> void Foo1 (T const *a) {a (1);} // #2 +template <typename T> void Foo1 (T *); +template <typename T> void Foo1 (T const *a) {a (1);} // { dg-error "too many arguments" } template <typename T> T const *Foo2 (T *); -template <typename T> void Foo3 (T *, T const * = 0); // { dg-message "note" } +template <typename T> void Foo3 (T *, T const * = 0); void Bar () { - Foo1 (&Baz); // #1 + Foo1 (&Baz); // { dg-message "required from here" } Foo2 (&Baz); Foo3 (&Baz); - Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" } - // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 21 } + Foo3 (&Baz, &Baz); }
Hi, On 07/09/2014 12:26 AM, Jason Merrill wrote: > I'd rather handle this in check_cv_quals_for_unify. Yes, the below passes testing. Thanks, Paolo. ///////////////////////// /cp 2014-07-09 Paolo Carlini <paolo.carlini@oracle.com> DR 1584 PR c++/57466 * pt.c (check_cv_quals_for_unify): Implement resolution, disregard cv-qualifiers of function types. /testsuite 2014-07-09 Paolo Carlini <paolo.carlini@oracle.com> DR 1584 PR c++/57466 * g++.dg/template/pr57466.C: New. * g++.dg/cpp0x/pr57466.C: Likewise. * g++.dg/template/unify6.C: Update.