diff options
author | Mark Mitchell <mark@markmitchell.com> | 1998-10-21 09:53:40 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-10-21 09:53:40 +0000 |
commit | 3932261a55eb9840491d2cee5bb58d6fff0533fa (patch) | |
tree | 9768c9c789a7b2a0a685cf74859c95d943a2cae0 /gcc/c-common.c | |
parent | 52e90c5508e2a90aaf2e85d923b175f4d9a92dc5 (diff) | |
download | gcc-3932261a55eb9840491d2cee5bb58d6fff0533fa.zip gcc-3932261a55eb9840491d2cee5bb58d6fff0533fa.tar.gz gcc-3932261a55eb9840491d2cee5bb58d6fff0533fa.tar.bz2 |
invoke.texi: Document -flang-isoc9x.
* invoke.texi: Document -flang-isoc9x.
* Makefile.in (OBJS): Add splay-tree.o.
(c-common.o): Depend on rtl.h.
(splay-tree.o): List dependencies and provide build rule.
* rtl.h (record_alias_subset): New function.
* alias.c: Include splay-tree.h.
(alias_set_entry): New type.
(CHECK_ALIAS_SETS_FOR_CONSISTENCY): Remove.
(DIFFERENT_ALIAS_SETS_P): Use mem_in_disjoint_alias_sets_p.
(mems_in_disjoin_alias_sets_p): New function.
(alias_set_compare): Likewise.
(insert_subset_children): Likewise.
(get_alias_set_entry): Likewise.
* tree.h (TYPE_RESTRICT): New macro.
(TYPE_UNQUALIFIED): New manifest constant.
(TYPE_QUAL_CONST): Likewise
(TYPE_QUAL_VOLATILE): Likewise.
(TYPE_QUAL_RESTRICT): Likewise.
(tree_type): Add restrict_flag. Reduce count of free bits.
(DECL_POINTER_ALIAS_SET): New macro.
(DECL_POINTER_ALIAS_SET_KNOWN_P): Likewise.
(tree_decl): Add pointer_alias_set.
(build_qualified_type): New function.
(build_type_variant): Define in terms of build_qualified_type.
* tree.c (set_type_quals): New function.
(make_node): Initializae DECL_POINTER_ALIAS_SET.
(build_type_attribute_variant): Use build_qualified_type and
set_type_quals.
(build_type_variant): Rename, and modify, to become...
(build_qualified_type): New function.
(build_complex_type): Use set_type_quals.
* c-tree.h (C_TYPE_OBJECT_P): New macro.
(C_TYPE_FUNCTION_P): Likewise.
(C_TYPE_INCOMPLETE_P): Likewise.
(C_TYPE_OBJECT_OR_INCOMPLETE_P): Likewise.
(c_apply_type_quals_to_decl): New function.
(c_build_qualified_type): New function.
(c_build_type_variant): Define in terms of c_build_qualified_type.
(flag_isoc9x): Declare.
* c-typeck.c (qualify_type): Use c_build_qualified_type.
(common_type): Change to use TYPE_QUALS.
(comptypes): Likewise.
(convert_for_assignment): Likewise.
* c-aux-info.c (gen_type): Likewise. Deal with `restrict'.
* c-decl.c (flag_isoc9x): Define.
(c_decode_option): Handle -flang-isoc9x.
(grokdeclarator): Update to handle restrict. Use TYPE_QUALS,
c_build_qualified_type, etc. Use c_apply_type_quals_to_decl.
* c-lex.c (init_lex): Deal with restrict.
(init_lex): Don't treat restrict as a reserved word in
-traditional mode, or without -flang-isoc9x.
* c-lex.h (rid): Add RID_RESTRICT.
* c-parse.gperf (restrict, __restrict, __restrict__): Make
equivalent to RID_RESTRICT.
* c-parse.in (TYPE_QUAL): Update comment.
* c-common.c: Include rtl.h.
(c_find_base_decl): New function.
(c_build_type_variant): Rename, and modify, to become ...
(c_build_qualified_type): New function.
(c_apply_type_quals_to_decl): Likewise.
(c_get_alias_set): For INDIRECT_REFs, check to see if we can find
a particular alias set for the reference.
* toplev.c (documented_lang_options): Add -flang-isoc9x.
From-SVN: r23212
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 133 |
1 files changed, 128 insertions, 5 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index a7b1ff1..4aaeb3c 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "output.h" #include "c-pragma.h" +#include "rtl.h" #if USE_CPPLIB #include "cpplib.h" @@ -66,6 +67,7 @@ static void init_attributes PROTO((void)); static void record_function_format PROTO((tree, tree, enum format_type, int, int)); static void record_international_format PROTO((tree, tree, int)); +static tree c_find_base_decl PROTO((tree)); /* Keep a stack of if statements. We record the number of compound statements seen up to the if keyword, as well as the line number @@ -2995,15 +2997,126 @@ get_directive_line (finput) down to the element type of an array. */ tree -c_build_type_variant (type, constp, volatilep) +c_build_qualified_type (type, type_quals) tree type; - int constp, volatilep; + int type_quals; { + /* 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. */ + if ((type_quals & TYPE_QUAL_RESTRICT) + && (!POINTER_TYPE_P (type) + || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))) + { + error ("invalid use of `restrict'"); + type_quals &= ~TYPE_QUAL_RESTRICT; + } + if (TREE_CODE (type) == ARRAY_TYPE) - return build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), + return build_array_type (c_build_qualified_type (TREE_TYPE (type), + type_quals), TYPE_DOMAIN (type)); - return build_type_variant (type, constp, volatilep); + return build_qualified_type (type, type_quals); +} + +/* Apply the TYPE_QUALS to the new DECL. */ + +void +c_apply_type_quals_to_decl (type_quals, decl) + int type_quals; + tree decl; +{ + if (type_quals & TYPE_QUAL_CONST) + TREE_READONLY (decl) = 1; + if (type_quals & TYPE_QUAL_VOLATILE) + { + TREE_SIDE_EFFECTS (decl) = 1; + TREE_THIS_VOLATILE (decl) = 1; + } + if ((type_quals & TYPE_QUAL_RESTRICT) && flag_strict_aliasing) + { + /* No two restricted pointers can point at the same thing. + However, a restricted pointer can point at the same thing as + an unrestricted pointer, if that unrestricted pointer is + based on the restricted pointer. So, we make the alias set + for the restricted pointer a subset of the alias set for the + type pointed to by the type of the decl. */ + + int pointed_to_alias_set + = get_alias_set (TREE_TYPE (TREE_TYPE (decl))); + + if (!pointed_to_alias_set) + /* It's not legal to make a subset of alias set zero. */ + ; + else + { + DECL_POINTER_ALIAS_SET (decl) = new_alias_set (); + record_alias_subset (pointed_to_alias_set, + DECL_POINTER_ALIAS_SET (decl)); + } + } +} + +/* T is an expression with pointer type. Find the DECL on which this + expression is based. (For example, in `a[i]' this would be `a'.) + If there is no such DECL, or a unique decl cannot be determined, + NULL_TREE is retured. */ + +static tree +c_find_base_decl (t) + tree t; +{ + int i; + tree decl; + + if (t == NULL_TREE || t == error_mark_node) + return NULL_TREE; + + if (!POINTER_TYPE_P (TREE_TYPE (t))) + return NULL_TREE; + + decl = NULL_TREE; + + if (TREE_CODE (t) == FIELD_DECL + || TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == VAR_DECL) + /* Aha, we found a pointer-typed declaration. */ + return t; + + /* It would be nice to deal with COMPONENT_REFs here. If we could + tell that `a' and `b' were the same, then `a->f' and `b->f' are + also the same. */ + + /* Handle general expressions. */ + switch (TREE_CODE_CLASS (TREE_CODE (t))) + { + case '1': + case '2': + case '3': + for (i = tree_code_length [(int) TREE_CODE (t)]; --i >= 0;) + { + tree d = c_find_base_decl (TREE_OPERAND (t, i)); + if (d) + { + if (!decl) + decl = d; + else if (d && d != decl) + /* Two different declarations. That's confusing; let's + just assume we don't know what's going on. */ + decl = NULL_TREE; + } + } + break; + + default: + break; + } + + return decl; } /* Return the typed-based alias set for T, which may be an expression @@ -3044,6 +3157,16 @@ c_get_alias_set (t) says that such accesses have implementation-defined behavior. */ return 0; + if (TREE_CODE (t) == INDIRECT_REF) + { + /* Check for accesses through restrict-qualified pointers. */ + tree decl = c_find_base_decl (TREE_OPERAND (t, 0)); + + if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl)) + /* We use the alias set indicated in the declaration. */ + return DECL_POINTER_ALIAS_SET (decl); + } + /* From here on, only the type matters. */ if (TYPE_ALIAS_SET_KNOWN_P (type)) |