diff options
author | Jason Merrill <jason@redhat.com> | 2003-10-09 04:38:46 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2003-10-09 04:38:46 -0400 |
commit | 4b011bbf6bbe244569bf18209dc7bce6a98dd224 (patch) | |
tree | d0f777b45d19a136899a383c83866e289a331465 /gcc/c-common.c | |
parent | e913996db1ff90fd5ae6fc7940c1f8a6fe9d10ea (diff) | |
download | gcc-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.c | 40 |
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. */ |