From: Jason Merrill Date: Thu, 9 Oct 2003 08:38:46 +0000 (-0400) Subject: re PR middle-end/6392 (Problems with __restrict__ type qualifier (array)) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4b011bbf6bbe244569bf18209dc7bce6a98dd224;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32165693ab1..cd3b6d9d8ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2003-10-09 Jason Merrill + 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 cef633aac88..b58eda14966 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 b7cf0299843..da318cfc9a2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2003-10-09 Jason Merrill + 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 109f7e52f18..f99b3168da6 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);