This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: build_type_variant() and the restrict type qualifier
- To: Gary Funck <gary at Intrepid dot Com>
- Subject: Re: build_type_variant() and the restrict type qualifier
- From: "Joseph S. Myers" <jsm28 at cam dot ac dot uk>
- Date: Tue, 27 Feb 2001 01:15:04 +0000 (GMT)
- cc: <gcc at gcc dot gnu dot org>
On Mon, 26 Feb 2001, Gary Funck wrote:
> In gcc 2.95.2, tree.h (line 1549), build_type_variant is defined as a macro:
Please refer to current mainline CVS. For all new development, the 2.95
branch should be considered obsolete.
> 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.)
I don't know about g++. I don't know about dwarf2out.c.
> 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));
I don't see why not - functions shouldn't be restrict qualified.
> /* 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?
In this case, TYPE_QUAL_RESTRICT should be propagated. I see nothing in
the standard to indicate otherwise; while the restrict qualifier has no
effect when appearing in the type of part of an expression, only when as
part of a declaration it designates an object as a restrict-qualified
pointer, I think GCC is wrong not to warn about
int *restrict foo;
int **bar = &foo;
discarding qualifiers.
In the case of conditional expressions, whether TYPE_QUAL_RESTRICT gets
propagated shouldn't matter for strictly conforming programs; while
qualifiers are (in the standard) lost when lvalues become rvalues, a s.c.
program can't detect this (though use of __typeof__ can). GCC needs to
propagate type qualifiers here to handle properly its extension of
conditional expressions as lvalues.
> 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?
Examine and understand each individual case before making the change. Add
testcases if you think what GCC did before was wrong. Check that restrict
qualifiers only have effects when used in declarations, not as part of the
types of expressions.
--
Joseph S. Myers
jsm28@cam.ac.uk