Patch for template unification with arrays
Mark Mitchell
mmitchell@usa.net
Wed Feb 11 16:02:00 GMT 1998
Jason --
Here's a patch for code like this:
struct foo {
template <typename T, int N>
static T* array_end(T(&array)[N]) { return &array[N]; }
};
main(int ac, char* av[]) {
int i[] = {1,2,3,4,5,6,7};
int* e = foo::array_end(i);
}
which didn't use to work correctly. Is it OK to check this in? Also,
why does call.c contain the following, in build_new_function_call:
if (! any_viable (candidates))
{
if (candidates && ! candidates->next)
return build_function_call (candidates->fn, args);
This code allows (silently) a function call to succeed if there is
only one candidate. Furthermore, we don't do this in other places
in call.c so member functions are not treated in this lenient
fashion.
--
Mark Mitchell mmitchell@usa.net
Stanford University http://www.stanford.edu
Wed Feb 11 16:01:20 1998 Mark Mitchell <mmitchell@usa.net>
* decl.c (complete_array_type): Build index types on the permanent
obstack.
(grokdeclarator): Likewise.
* pt.c (tsubst): Always create index types with build_index_type
so that we get canonical index types.
Index: gcc/cp/decl.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/decl.c,v
retrieving revision 1.25
diff -c -p -r1.25 decl.c
*** decl.c 1998/02/11 19:03:02 1.25
--- decl.c 1998/02/11 22:47:02
*************** complete_array_type (type, initial_value
*** 7297,7303 ****
{
tree itype;
! TYPE_DOMAIN (type) = build_index_type (maxindex);
if (! TREE_TYPE (maxindex))
TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
if (initial_value)
--- 7297,7311 ----
{
tree itype;
! /* We make sure to build the index type on the permanent_obstack
! so that we will get a canonical index type. These types must
! be canonical since some comparisons to see if two array types are
! the same depend on checking the TYPE_MAIN_VARIANT of the
! array, and those fields will only be the same if the
! index_types are canonical. */
! push_obstacks (&permanent_obstack, &permanent_obstack);
! TYPE_DOMAIN (type) = build_index_type (copy_to_permanent (maxindex));
! pop_obstacks ();
if (! TREE_TYPE (maxindex))
TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
if (initial_value)
*************** grokdeclarator (declarator, declspecs, d
*** 8852,8867 ****
/* If we're a parm, we need to have a permanent type so
mangling checks for re-use will work right. If both the
element and index types are permanent, the array type
! will be, too. */
! if (decl_context == PARM
! && allocation_temporary_p () && TREE_PERMANENT (type))
! {
! push_obstacks (&permanent_obstack, &permanent_obstack);
! itype = build_index_type (itype);
! pop_obstacks ();
! }
! else
! itype = build_index_type (itype);
dont_grok_size:
resume_momentary (yes);
--- 8860,8871 ----
/* If we're a parm, we need to have a permanent type so
mangling checks for re-use will work right. If both the
element and index types are permanent, the array type
! will be, too. In fact, the index type must always
! be canonical; see the comment in
! complete_array_type. */
! push_obstacks (&permanent_obstack, &permanent_obstack);
! itype = build_index_type (itype);
! pop_obstacks ();
dont_grok_size:
resume_momentary (yes);
Index: gcc/cp/pt.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/pt.c,v
retrieving revision 1.26
diff -c -p -r1.26 pt.c
*** pt.c 1998/02/11 19:03:37 1.26
--- pt.c 1998/02/11 21:49:04
*************** tsubst (t, args, nargs, in_decl)
*** 3889,3894 ****
--- 3889,3897 ----
tree r;
if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
return t;
+ /* The tsbust'd domain type is not the canonical one, most
+ likely, so we must recreate it. */
+ domain = build_index_type (TYPE_MAX_VALUE (domain));
r = build_cplus_array_type (type, domain);
return r;
}
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.pt
Index: gcc/testsuite/g++.old-deja/g++.pt/memtemp69.C
===================================================================
RCS file: memtemp69.C
diff -N memtemp69.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- memtemp69.C Wed Feb 11 14:25:00 1998
***************
*** 0 ****
--- 1,27 ----
+ struct S
+ {
+ template <class T>
+ void f(T (&i)[7])
+ {}
+
+ void g()
+ {
+ int i[] = {1, 2, 3, 4, 5, 6, 7};
+ f(i);
+ int j[7];
+ f(j);
+ }
+ };
+
+ struct foo {
+ template <typename T, int N>
+ static T* array_end(T(&array)[N]) { return &array[N]; }
+ };
+
+ main(int ac, char* av[]) {
+ S s;
+ s.g();
+ int i[] = {1,2,3,4,5};
+ int* e = foo::array_end(i);
+ }
+
More information about the Gcc-bugs
mailing list