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
This commit is contained in:
parent
e913996db1
commit
4b011bbf6b
@ -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.
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
||||
|
106
gcc/cp/tree.c
106
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user