This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

build_type_variant() and the restrict type qualifier


In gcc 2.95.2, tree.h (line 1549), build_type_variant is defined as a macro:

/* Like build_qualified_type, but only deals with the `const' and
   `volatile' qualifiers.  This interface is retained for backwards
   compatiblity with the various front-ends; new code should use
   build_qualified_type instead.  */

#define build_type_variant(TYPE, CONST_P, VOLATILE_P)                   \
  build_qualified_type (TYPE,                                           \
                        ((CONST_P) ? TYPE_QUAL_CONST : 0)               \
                        | ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))


I'm interested in adding some additional type qualifiers, and would
prefer not to have to tack them on to build_type_variant, but
instead, to rewrite the calls into calls to build_qualified_type(),
and to use the TYPE_QUALS() macro to access the type
qualifiers of the source type.  I don't see any problems with this
except for the fact that the existing build_type_variant() call
ignores the C99 "restrict" type qualifier (sec. 6.7.3):

    7 An object that is accessed through a restrict-qualified
    pointer has a special association with that pointer. This
    association, defined in 6.7.3.1 below, requires that all
    accesses to that object use, directly or indirectly, the
    value of that particular pointer. The intended use of
    the restrict qualifier (like the register storage class) is
    to promote optimization, and deleting all instances of the
    qualifier from all preprocessing translation units
    composing a conforming program does not change its meaning
    (i.e., observable behavior).


In gcc 2.95.2, build_type_variant() is used in the following
filies:

c-common.c
c-decl.c
c-typeck.c
dwarf2out.c
cp/decl.c

ch/actions.c
ch/decl.c
ch/except.c
ch/expr.c
f/com.c
f/ste.c

A quick review of those uses of build_type_variant() indicates that
the Chill (ch/*) and Fortran (f/*) files can be ignored for the
purposes of answering the following question:

Q: In gcc and g++, can the calls to build_type_variant() be rewritten
into calls to build_qualified_type() with TYPE_QUALS() use to extract
the qualifiers of the source type, where needed?  (This would have the
effect of propagating TYPE_QUAL_RESTRICT, as well as any other
type qualifiers that are added into the type definition.)

Here's an example/two.  In c-typeck.c (line 1545):

  /* Convert anything with function type to a pointer-to-function.  */
  if (TREE_CODE (function) == FUNCTION_DECL)
    {
      name = DECL_NAME (function);
      assembler_name = DECL_ASSEMBLER_NAME (function);

      /* Differs from default_conversion by not setting TREE_ADDRESSABLE
         (because calling an inline function does not mean the function
         needs to be separately compiled).  */
      fntype = build_type_variant (TREE_TYPE (function),
                                   TREE_READONLY (function),
                                   TREE_THIS_VOLATILE (function));
      fundecl = function;
      function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
    }

Is it acceptable for the call above to build_type_variant to be
rewritten as:

     fntype = build_qualified_type (TREE_TYPE (function), TYPE_QUALS(function));


It appears that the only additional qualifier which *might*
be propagated, would be TYPE_QUAL_RESTRICT.

Heer's another example, (c-typeck.c line 3106):

      /* If the lvalue is const or volatile, merge that into the type
         to which the address will point.  Note that you can't get a
         restricted pointer by taking the address of something, so we
         only have to deal with `const' and `volatile' here.  */
      if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
          || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
        {
          if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
            argtype = c_build_type_variant (argtype,
                                            TREE_READONLY (arg),
                                            TREE_THIS_VOLATILE (arg));
        }

In this case, it is a little less clear whether the following rewrite
would be acceptable:

          if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
            argtype = build_qualified_type (argtype, TYPE_QUALS (arg));

because TYPE_QUALS will also propagate TYPE_QUAL_RESTRICT.
Might TYPE_QUAL_RESTRICT have been also asserted in `arg'?
If TYPE_QUAL_RESTRICT was asserted, should it in fact be
propagated into `argtype' above?

To summarize - if calls to build_type_variant() and c_build_type_variant()
are rewritten into calls to build_qualified_type(), is it acceptable to
pass the existing type qualifiers (where required) by simply calling
TYPE_QUALS()? (The difficulty is that TYPE_QUALS() may also return
TYPE_QUAL_RESTRICT and any additional type qualifiers that might be added).
Or, should the type qualifiers of interest be restricted to
only TYPE_QUAL_CONST, and TYPE_QUAL_VOLATILE?

A secondary question is; Is TYPE_QUAL_RESTRICT not at present
(in gcc 2.95.2) not being propagated correctly in the places
where build_type_variant() and c_build_type_variant() are being
called, because these older calls deal only with `const' and
`volatile' qualifiers?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]