aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-common.c40
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/tree.c106
4 files changed, 87 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3216569..cd3b6d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2003-10-09 Jason Merrill <jason@redhat.com>
+ PR c++/6392
+ * 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.
+
* coverage.c (build_ctr_info_value): Use build_decl to make a
VAR_DECL.
(create_coverage): Likewise.
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. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b7cf029..da318cf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2003-10-09 Jason Merrill <jason@redhat.com>
+ PR c++/6392
+ * tree.c (build_cplus_array_type): Handle all quals the same.
+ (cp_build_qualified_type_real): Look through arrays first.
+
* tree.c (build_cplus_new): Use build_decl to create a VAR_DECL.
(build_target_expr_with_type): Likewise.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 109f7e5..f99b316 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -367,16 +367,14 @@ build_cplus_array_type (tree elt_type, tree index_type)
{
tree t;
int type_quals = cp_type_quals (elt_type);
- int cv_quals = type_quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
- int other_quals = type_quals & ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
- if (cv_quals)
- elt_type = cp_build_qualified_type (elt_type, other_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
t = build_cplus_array_type_1 (elt_type, index_type);
- if (cv_quals)
- t = cp_build_qualified_type (t, cv_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ t = cp_build_qualified_type (t, type_quals);
return t;
}
@@ -420,54 +418,6 @@ cp_build_qualified_type_real (tree type,
if (type_quals == cp_type_quals (type))
return type;
- /* A reference, fucntion or method type shall not be cv qualified.
- [dcl.ref], [dct.fct] */
- if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
- && (TREE_CODE (type) == REFERENCE_TYPE
- || TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE))
- {
- bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- if (TREE_CODE (type) != REFERENCE_TYPE)
- bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- }
-
- /* A restrict-qualified type must be a pointer (or reference)
- to object or incomplete type. */
- if ((type_quals & TYPE_QUAL_RESTRICT)
- && TREE_CODE (type) != TEMPLATE_TYPE_PARM
- && TREE_CODE (type) != TYPENAME_TYPE
- && !POINTER_TYPE_P (type))
- {
- bad_quals |= TYPE_QUAL_RESTRICT;
- type_quals &= ~TYPE_QUAL_RESTRICT;
- }
-
- if (bad_quals == TYPE_UNQUALIFIED)
- /*OK*/;
- else if (!(complain & (tf_error | tf_ignore_bad_quals)))
- return error_mark_node;
- else if (bad_func_quals && !(complain & tf_error))
- return error_mark_node;
- else
- {
- if (complain & tf_ignore_bad_quals)
- /* We're not going to warn about constifying things that can't
- be constified. */
- bad_quals &= ~TYPE_QUAL_CONST;
- bad_quals |= bad_func_quals;
- if (bad_quals)
- {
- tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
-
- if (!(complain & tf_ignore_bad_quals)
- || bad_func_quals)
- error ("`%V' qualifiers cannot be applied to `%T'",
- bad_type, type);
- }
- }
-
if (TREE_CODE (type) == ARRAY_TYPE)
{
/* In C++, the qualification really applies to the array element
@@ -522,6 +472,54 @@ cp_build_qualified_type_real (tree type,
return build_ptrmemfunc_type (t);
}
+ /* A reference, function or method type shall not be cv qualified.
+ [dcl.ref], [dct.fct] */
+ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ {
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ }
+
+ /* A restrict-qualified type must be a pointer (or reference)
+ to object or incomplete type. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (type) != TYPENAME_TYPE
+ && !POINTER_TYPE_P (type))
+ {
+ bad_quals |= TYPE_QUAL_RESTRICT;
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
+ if (bad_quals == TYPE_UNQUALIFIED)
+ /*OK*/;
+ else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+ return error_mark_node;
+ else if (bad_func_quals && !(complain & tf_error))
+ return error_mark_node;
+ else
+ {
+ if (complain & tf_ignore_bad_quals)
+ /* We're not going to warn about constifying things that can't
+ be constified. */
+ bad_quals &= ~TYPE_QUAL_CONST;
+ bad_quals |= bad_func_quals;
+ if (bad_quals)
+ {
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+
+ if (!(complain & tf_ignore_bad_quals)
+ || bad_func_quals)
+ error ("`%V' qualifiers cannot be applied to `%T'",
+ bad_type, type);
+ }
+ }
+
/* Retrieve (or create) the appropriately qualified variant. */
result = build_qualified_type (type, type_quals);