aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2003-10-09 04:38:46 -0400
committerJason Merrill <jason@gcc.gnu.org>2003-10-09 04:38:46 -0400
commit4b011bbf6bbe244569bf18209dc7bce6a98dd224 (patch)
treed0f777b45d19a136899a383c83866e289a331465 /gcc/c-common.c
parente913996db1ff90fd5ae6fc7940c1f8a6fe9d10ea (diff)
downloadgcc-4b011bbf6bbe244569bf18209dc7bce6a98dd224.zip
gcc-4b011bbf6bbe244569bf18209dc7bce6a98dd224.tar.gz
gcc-4b011bbf6bbe244569bf18209dc7bce6a98dd224.tar.bz2
re PR middle-end/6392 (Problems with __restrict__ type qualifier (array))
PR c++/6392 * cp/tree.c (build_cplus_array_type): Handle all quals the same. (cp_build_qualified_type_real): Look through arrays first. * c-common.c (c_build_qualified_type): Look through arrays first. (c_apply_type_quals_to_decl): Look through arrays. * c-common.c (c_apply_type_quals_to_decl): Unset TREE_READONLY for types with constructors. From-SVN: r72259
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index cef633a..b58eda1 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2766,13 +2766,14 @@ static tree builtin_function_2 (const char *, const char *, tree, tree,
tree
c_build_qualified_type (tree type, int type_quals)
{
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
+ TYPE_DOMAIN (type));
+
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
- REFERENCE_TYPEs, which is appropriate for C++. Unfortunately,
- the C++ front-end also use POINTER_TYPE for pointer-to-member
- values, so even though it should be illegal to use `restrict'
- with such an entity we don't flag that here. Thus, special case
- code for that case is required in the C++ front-end. */
+ REFERENCE_TYPEs, which is appropriate for C++. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
@@ -2781,10 +2782,6 @@ c_build_qualified_type (tree type, int type_quals)
type_quals &= ~TYPE_QUAL_RESTRICT;
}
- if (TREE_CODE (type) == ARRAY_TYPE)
- return build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
return build_qualified_type (type, type_quals);
}
@@ -2793,9 +2790,16 @@ c_build_qualified_type (tree type, int type_quals)
void
c_apply_type_quals_to_decl (int type_quals, tree decl)
{
- if ((type_quals & TYPE_QUAL_CONST)
- || (TREE_TYPE (decl)
- && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE))
+ tree type = TREE_TYPE (decl);
+
+ if (((type_quals & TYPE_QUAL_CONST)
+ || (type && TREE_CODE (type) == REFERENCE_TYPE))
+ /* An object declared 'const' is only readonly after it is
+ initialized. We don't have any way of expressing this currently,
+ so we need to be conservative and unset TREE_READONLY for types
+ with constructors. Otherwise aliasing code will ignore stores in
+ an inline constructor. */
+ && !(type && TYPE_NEEDS_CONSTRUCTING (type)))
TREE_READONLY (decl) = 1;
if (type_quals & TYPE_QUAL_VOLATILE)
{
@@ -2804,11 +2808,15 @@ c_apply_type_quals_to_decl (int type_quals, tree decl)
}
if (type_quals & TYPE_QUAL_RESTRICT)
{
- if (!TREE_TYPE (decl)
- || !POINTER_TYPE_P (TREE_TYPE (decl))
- || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
+ while (type && TREE_CODE (type) == ARRAY_TYPE)
+ /* Allow 'restrict' on arrays of pointers.
+ FIXME currently we just ignore it. */
+ type = TREE_TYPE (type);
+ if (!type
+ || !POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))
error ("invalid use of `restrict'");
- else if (flag_strict_aliasing)
+ else if (flag_strict_aliasing && type == TREE_TYPE (decl))
/* Indicate we need to make a unique alias set for this pointer.
We can't do it here because it might be pointing to an
incomplete type. */