Revert "Fix the remaining PR c++/24666 blockers"
gcc/cp/ChangeLog: Revert: 2016-01-18 Patrick Palka <ppalka@gcc.gnu.org> PR c++/11858 PR c++/24663 PR c++/24664 * decl.c (grokdeclarator): Don't decay array parameter type to a pointer type if it's dependent. (grokparms): Invoke strip_top_quals instead of directly invoking cp_build_qualified_type. * pt.c (decay_dependent_array_parm_type): New static function. (type_unification_real): Call decay_dependent_array_parm_type to decay a dependent array parameter type to its corresponding pointer type before unification. (more_specialized_fn): Likewise. (get_bindings): Likewise. * tree.c (cp_build_qualified_type): Trivial typofix in documentation. gcc/testsuite/ChangeLog: Revert: 2016-01-18 Patrick Palka <ppalka@gcc.gnu.org> PR c++/11858 PR c++/24663 PR c++/24664 * g++.dg/template/pr11858.C: New test. * g++.dg/template/pr24663.C: New test. * g++.dg/template/unify12.C: New test. * g++.dg/template/unify13.C: New test. * g++.dg/template/unify14.C: New test. * g++.dg/template/unify15.C: New test. * g++.dg/template/unify16.C: New test. * g++.dg/template/unify17.C: New test. From-SVN: r232778
This commit is contained in:
parent
cefadad11a
commit
a59b92b0c7
13 changed files with 43 additions and 222 deletions
|
@ -1,3 +1,24 @@
|
|||
2016-01-24 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
Revert:
|
||||
2016-01-18 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
PR c++/11858
|
||||
PR c++/24663
|
||||
PR c++/24664
|
||||
* decl.c (grokdeclarator): Don't decay array parameter type to
|
||||
a pointer type if it's dependent.
|
||||
(grokparms): Invoke strip_top_quals instead of directly invoking
|
||||
cp_build_qualified_type.
|
||||
* pt.c (decay_dependent_array_parm_type): New static function.
|
||||
(type_unification_real): Call decay_dependent_array_parm_type
|
||||
to decay a dependent array parameter type to its corresponding
|
||||
pointer type before unification.
|
||||
(more_specialized_fn): Likewise.
|
||||
(get_bindings): Likewise.
|
||||
* tree.c (cp_build_qualified_type): Trivial typofix in
|
||||
documentation.
|
||||
|
||||
2016-01-23 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/58109
|
||||
|
|
|
@ -10898,13 +10898,8 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
/* Withhold decaying a dependent array type so that that during
|
||||
instantiation we can detect type deduction failure cases such as
|
||||
creating an array of void, creating a zero-size array, etc. */
|
||||
if (dependent_type_p (type))
|
||||
;
|
||||
else
|
||||
type = build_pointer_type (TREE_TYPE (type));
|
||||
/* Transfer const-ness of array into that of type pointed to. */
|
||||
type = build_pointer_type (TREE_TYPE (type));
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
array_parameter_p = true;
|
||||
}
|
||||
|
@ -11705,8 +11700,7 @@ grokparms (tree parmlist, tree *parms)
|
|||
|
||||
/* Top-level qualifiers on the parameters are
|
||||
ignored for function types. */
|
||||
type = strip_top_quals (type);
|
||||
|
||||
type = cp_build_qualified_type (type, 0);
|
||||
if (TREE_CODE (type) == METHOD_TYPE)
|
||||
{
|
||||
error ("parameter %qD invalidly declared method type", decl);
|
||||
|
|
27
gcc/cp/pt.c
27
gcc/cp/pt.c
|
@ -17789,23 +17789,6 @@ fn_type_unification (tree fn,
|
|||
return r;
|
||||
}
|
||||
|
||||
/* TYPE is the type of a function parameter. If TYPE is a (dependent)
|
||||
ARRAY_TYPE, return the corresponding POINTER_TYPE to which it decays.
|
||||
Otherwise return TYPE. (We shouldn't see non-dependent ARRAY_TYPE
|
||||
parameters because they get decayed as soon as they are declared.) */
|
||||
|
||||
static tree
|
||||
decay_dependent_array_parm_type (tree type)
|
||||
{
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
gcc_assert (uses_template_parms (type));
|
||||
return type_decays_to (type);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Adjust types before performing type deduction, as described in
|
||||
[temp.deduct.call] and [temp.deduct.conv]. The rules in these two
|
||||
sections are symmetric. PARM is the type of a function parameter
|
||||
|
@ -18244,8 +18227,6 @@ type_unification_real (tree tparms,
|
|||
arg = args[ia];
|
||||
++ia;
|
||||
|
||||
parm = decay_dependent_array_parm_type (parm);
|
||||
|
||||
if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
|
||||
explain_p))
|
||||
return 1;
|
||||
|
@ -20257,9 +20238,6 @@ more_specialized_fn (tree pat1, tree pat2, int len)
|
|||
len = 0;
|
||||
}
|
||||
|
||||
arg1 = decay_dependent_array_parm_type (arg1);
|
||||
arg2 = decay_dependent_array_parm_type (arg2);
|
||||
|
||||
if (TREE_CODE (arg1) == REFERENCE_TYPE)
|
||||
{
|
||||
ref1 = TYPE_REF_IS_RVALUE (arg1) + 1;
|
||||
|
@ -20545,10 +20523,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
|
|||
for (arg = decl_arg_types, ix = 0;
|
||||
arg != NULL_TREE && arg != void_list_node;
|
||||
arg = TREE_CHAIN (arg), ++ix)
|
||||
{
|
||||
args[ix] = TREE_VALUE (arg);
|
||||
args[ix] = decay_dependent_array_parm_type (args[ix]);
|
||||
}
|
||||
args[ix] = TREE_VALUE (arg);
|
||||
|
||||
if (fn_type_unification (fn, explicit_args, targs,
|
||||
args, ix,
|
||||
|
|
|
@ -1012,7 +1012,7 @@ c_build_qualified_type (tree type, int type_quals, tree /* orig_qual_type */,
|
|||
arrays correctly. In particular, if TYPE is an array of T's, and
|
||||
TYPE_QUALS is non-empty, returns an array of qualified T's.
|
||||
|
||||
COMPLAIN determines how to deal with ill-formed qualifications. If
|
||||
FLAGS determines how to deal with ill-formed qualifications. If
|
||||
tf_ignore_bad_quals is set, then bad qualifications are dropped
|
||||
(this is permitted if TYPE was introduced via a typedef or template
|
||||
type parameter). If bad qualifications are dropped and tf_warning
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
2016-01-24 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
Revert:
|
||||
2016-01-18 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
PR c++/11858
|
||||
PR c++/24663
|
||||
PR c++/24664
|
||||
* g++.dg/template/pr11858.C: New test.
|
||||
* g++.dg/template/pr24663.C: New test.
|
||||
* g++.dg/template/unify12.C: New test.
|
||||
* g++.dg/template/unify13.C: New test.
|
||||
* g++.dg/template/unify14.C: New test.
|
||||
* g++.dg/template/unify15.C: New test.
|
||||
* g++.dg/template/unify16.C: New test.
|
||||
* g++.dg/template/unify17.C: New test.
|
||||
|
||||
2016-01-24 Dominique d'Humieres <dominiq@lps.ens.fr>
|
||||
|
||||
PR fortran/68283
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
// PR c++/11858
|
||||
|
||||
template <typename T> struct S { static typename T::x f (); }; // { dg-error "" }
|
||||
template <class T> int f (int [sizeof(T::f())]);
|
||||
int const i = f<S<int> >(0); // { dg-error "no matching function" }
|
|
@ -1,22 +0,0 @@
|
|||
// PR c++/24663
|
||||
|
||||
template<int I> int f1 (char[I]);
|
||||
template<int I> int f1 (char p1 = I);
|
||||
int i = f1<0>(0);
|
||||
|
||||
template<typename T, int I> int f2 (T[I]); // { dg-error "" }
|
||||
int j = f2<int, 0>(0); // { dg-error "no matching function" }
|
||||
int k = f2<void, 1>(0); // { dg-error "no matching function" }
|
||||
|
||||
int o[5];
|
||||
int l = f2<int[5], 1>(&o);
|
||||
|
||||
template<int I> int f3 (char [][I]);
|
||||
template<int I> int f3 (char p1 = I);
|
||||
int x1 = f3<1>(0); // { dg-error "is ambiguous" }
|
||||
int x2 = f3<1>();
|
||||
|
||||
template<typename T, int I> int f4 (T [][I]); // { dg-error "" }
|
||||
int y1 = f4<void, 1>(0); // { dg-error "no matching function" }
|
||||
int y2 = f4<int (void), 1>(0); // { dg-error "no matching function" }
|
||||
int y3 = f4<int&, 1>(0); // { dg-error "no matching function" }
|
|
@ -1,46 +0,0 @@
|
|||
// { dg-do run }
|
||||
#include <cassert>
|
||||
|
||||
template<typename T, int I> int foo (T [I][I]) { return 0; }
|
||||
|
||||
template int foo (char [][6]);
|
||||
|
||||
template <typename T>
|
||||
int foo (T *)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int foo (T [3][3])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <int I>
|
||||
int foo (bool [I][I])
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
template <>
|
||||
int foo (bool [3][2])
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
char x[3];
|
||||
bool y[4];
|
||||
bool z[3][2];
|
||||
|
||||
int a = foo (&x);
|
||||
int b = foo (&y);
|
||||
int c = foo (z);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
assert (a == 1);
|
||||
assert (b == 2);
|
||||
assert (c == 3);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// { dg-do run }
|
||||
#include <cassert>
|
||||
|
||||
template<typename T, int I> int foo (T [I][I]) { return 0; }
|
||||
|
||||
template<typename T>
|
||||
int foo (T [3][2])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <>
|
||||
int foo (bool [3][2])
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool z[3][2];
|
||||
|
||||
int a = foo (z);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
assert (a == 2);
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
template <typename T, int X>
|
||||
void bar (T [X]) { }
|
||||
|
||||
template <typename T, int X>
|
||||
void bar (const T [X]) { }
|
|
@ -1,15 +0,0 @@
|
|||
// { dg-do run }
|
||||
#include <cassert>
|
||||
|
||||
template <typename T, int N>
|
||||
int bar (T (&) [N]) { return 0; }
|
||||
|
||||
template <typename T, int N>
|
||||
int bar (const T (&) [N]) { return 1; }
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
const int s[2] = { 0 };
|
||||
assert (bar (s) == 1);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
// { dg-do run }
|
||||
#include <cassert>
|
||||
|
||||
template <typename T>
|
||||
struct Foo
|
||||
{
|
||||
static int foo (T) { return 0; }
|
||||
};
|
||||
|
||||
template <typename T, int I>
|
||||
struct Foo<T[I]>
|
||||
{
|
||||
static int foo (T[I]) { return 1; }
|
||||
};
|
||||
|
||||
template <int I>
|
||||
struct Foo<char[I]>
|
||||
{
|
||||
static int foo (char[I]) { return 2; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Foo<T[5]>
|
||||
{
|
||||
static int foo (T[5]) { return 3; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Foo<char[5]>
|
||||
{
|
||||
static int foo (char[5]) { return 4; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Foo<const char[5]>
|
||||
{
|
||||
static int foo (const char[5]) { return 5; }
|
||||
};
|
||||
|
||||
int a = Foo<const char[5]>::foo (0);
|
||||
int b = Foo<char[5]>::foo (0);
|
||||
int c = Foo<bool[5]>::foo (0);
|
||||
int d = Foo<char[4]>::foo (0);
|
||||
int e = Foo<bool[4]>::foo (0);
|
||||
int f = Foo<char[]>::foo (0);
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
assert (a == 5);
|
||||
assert (b == 4);
|
||||
assert (c == 3);
|
||||
assert (d == 2);
|
||||
assert (e == 1);
|
||||
assert (f == 0);
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
void foo (int *);
|
||||
|
||||
template <typename T>
|
||||
void bar (void (T[5])); // { dg-error "array of 'void'" }
|
||||
|
||||
void
|
||||
baz (void)
|
||||
{
|
||||
bar (foo); // { dg-bogus "" }
|
||||
bar<void> (0); // { dg-error "no matching function" }
|
||||
}
|
Loading…
Add table
Reference in a new issue