Commit 0ceb0201 by Richard Guenther Committed by Richard Biener

alias.c (get_alias_set): Assign a single alias-set to all pointers.

2010-08-25  Richard Guenther  <rguenther@suse.de>

	* alias.c (get_alias_set): Assign a single alias-set to
	all pointers.
	* gimple.c (gimple_get_alias_set): Remove special handling
	for pointers.

	c-family/
	* c-common.c (c_common_get_alias_set): Remove special
	handling for pointers.

	* gcc.dg/alias-8.c: Adjust.

From-SVN: r163549
parent 22b139e1
2010-08-25 Richard Guenther <rguenther@suse.de>
* alias.c (get_alias_set): Assign a single alias-set to
all pointers.
* gimple.c (gimple_get_alias_set): Remove special handling
for pointers.
2010-08-25 Bernd Schmidt <bernds@codesourcery.com>
PR middle-end/45355
......
......@@ -761,6 +761,62 @@ get_alias_set (tree t)
else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t))
set = get_alias_set (TREE_TYPE (t));
/* From the former common C and C++ langhook implementation:
Unfortunately, there is no canonical form of a pointer type.
In particular, if we have `typedef int I', then `int *', and
`I *' are different types. So, we have to pick a canonical
representative. We do this below.
Technically, this approach is actually more conservative that
it needs to be. In particular, `const int *' and `int *'
should be in different alias sets, according to the C and C++
standard, since their types are not the same, and so,
technically, an `int **' and `const int **' cannot point at
the same thing.
But, the standard is wrong. In particular, this code is
legal C++:
int *ip;
int **ipp = &ip;
const int* const* cipp = ipp;
And, it doesn't make sense for that to be legal unless you
can dereference IPP and CIPP. So, we ignore cv-qualifiers on
the pointed-to types. This issue has been reported to the
C++ committee.
In addition to the above canonicalization issue, with LTO
we should also canonicalize `T (*)[]' to `T *' avoiding
alias issues with pointer-to element types and pointer-to
array types.
Likewise we need to deal with the situation of incomplete
pointed-to types and make `*(struct X **)&a' and
`*(struct X {} **)&a' alias. Otherwise we will have to
guarantee that all pointer-to incomplete type variants
will be replaced by pointer-to complete type variants if
they are available.
With LTO the convenient situation of using `void *' to
access and store any pointer type will also become
more apparent (and `void *' is just another pointer-to
incomplete type). Assigning alias-set zero to `void *'
and all pointer-to incomplete types is a not appealing
solution. Assigning an effective alias-set zero only
affecting pointers might be - by recording proper subset
relationships of all pointer alias-sets.
Pointer-to function types are another grey area which
needs caution. Globbing them all into one alias-set
or the above effective zero set would work.
For now just assign the same alias-set to all pointers.
That's simple and avoids all the above problems. */
else if (POINTER_TYPE_P (t)
&& t != ptr_type_node)
return get_alias_set (ptr_type_node);
/* Otherwise make a new alias set for this type. */
else
set = new_alias_set ();
......
2010-08-25 Richard Guenther <rguenther@suse.de>
* c-common.c (c_common_get_alias_set): Remove special
handling for pointers.
2010-08-20 Nathan Froyd <froydnj@codesourcery.com>
* c-common.c: Use FOR_EACH_VEC_ELT.
......
......@@ -4087,37 +4087,6 @@ c_common_get_alias_set (tree t)
if (t1 != t)
return get_alias_set (t1);
}
else if (POINTER_TYPE_P (t))
{
tree t1;
/* Unfortunately, there is no canonical form of a pointer type.
In particular, if we have `typedef int I', then `int *', and
`I *' are different types. So, we have to pick a canonical
representative. We do this below.
Technically, this approach is actually more conservative that
it needs to be. In particular, `const int *' and `int *'
should be in different alias sets, according to the C and C++
standard, since their types are not the same, and so,
technically, an `int **' and `const int **' cannot point at
the same thing.
But, the standard is wrong. In particular, this code is
legal C++:
int *ip;
int **ipp = &ip;
const int* const* cipp = ipp;
And, it doesn't make sense for that to be legal unless you
can dereference IPP and CIPP. So, we ignore cv-qualifiers on
the pointed-to types. This issue has been reported to the
C++ committee. */
t1 = build_type_no_quals (t);
if (t1 != t)
return get_alias_set (t1);
}
/* Handle the case of multiple type nodes referring to "the same" type,
which occurs with IMA. These share an alias set. FIXME: Currently only
......
......@@ -4582,63 +4582,6 @@ gimple_get_alias_set (tree t)
if (t1 != t)
return get_alias_set (t1);
}
else if (POINTER_TYPE_P (t))
{
/* From the common C and C++ langhook implementation:
Unfortunately, there is no canonical form of a pointer type.
In particular, if we have `typedef int I', then `int *', and
`I *' are different types. So, we have to pick a canonical
representative. We do this below.
Technically, this approach is actually more conservative that
it needs to be. In particular, `const int *' and `int *'
should be in different alias sets, according to the C and C++
standard, since their types are not the same, and so,
technically, an `int **' and `const int **' cannot point at
the same thing.
But, the standard is wrong. In particular, this code is
legal C++:
int *ip;
int **ipp = &ip;
const int* const* cipp = ipp;
And, it doesn't make sense for that to be legal unless you
can dereference IPP and CIPP. So, we ignore cv-qualifiers on
the pointed-to types. This issue has been reported to the
C++ committee. */
/* In addition to the above canonicalization issue with LTO
we should also canonicalize `T (*)[]' to `T *' avoiding
alias issues with pointer-to element types and pointer-to
array types.
Likewise we need to deal with the situation of incomplete
pointed-to types and make `*(struct X **)&a' and
`*(struct X {} **)&a' alias. Otherwise we will have to
guarantee that all pointer-to incomplete type variants
will be replaced by pointer-to complete type variants if
they are available.
With LTO the convenient situation of using `void *' to
access and store any pointer type will also become
more apparent (and `void *' is just another pointer-to
incomplete type). Assigning alias-set zero to `void *'
and all pointer-to incomplete types is a not appealing
solution. Assigning an effective alias-set zero only
affecting pointers might be - by recording proper subset
relationships of all pointer alias-sets.
Pointer-to function types are another grey area which
needs caution. Globbing them all into one alias-set
or the above effective zero set would work. */
/* For now just assign the same alias-set to all pointers.
That's simple and avoids all the above problems. */
if (t != ptr_type_node)
return get_alias_set (ptr_type_node);
}
return -1;
}
......
2010-08-25 Richard Guenther <rguenther@suse.de>
* gcc.dg/alias-8.c: Adjust.
2010-08-25 Bernd Schmidt <bernds@codesourcery.com>
* gcc.target/i386/combine-mul.c: New test.
......
......@@ -8,5 +8,5 @@ struct s {
void
func(struct s *ptr)
{
*(void **)&ptr->p = 0; /* { dg-warning "type-punned pointer" } */
*(void **)&ptr->p = 0; /* { dg-warning "type-punned pointer" "" { xfail *-*-* } } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment