This is the mail archive of the
mailing list for the GCC project.
'*' operation and TYPE_MAIN_VARIANT()
- From: "Gary Funck" <gary at intrepid dot com>
- To: "Gcc Mailing List" <gcc at gcc dot gnu dot org>
- Date: Thu, 8 Aug 2002 12:36:42 -0700
- Subject: '*' operation and TYPE_MAIN_VARIANT()
While working on GCC recently, I ran into an area of code in c-typeck.c that
raised a question regarding the sementics of the '*' (indirect operation),
and whether the code in build_indirect() is exactly as it should be. In
1325 tree t = TREE_TYPE (type);
1326 register tree ref = build1 (INDIRECT_REF,
1327 TYPE_MAIN_VARIANT (t),
1329 if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
1331 error ("dereferencing pointer to incomplete type");
1332 return error_mark_node;
1334 if (TREE_CODE (t) == VOID_TYPE)
1335 warning ("dereferencing `void *' pointer");
1337 /* We *must* set TREE_READONLY when dereferencing a
pointer to const,
1338 so that we get the proper error message if the result
1339 to assign to. Also, &* is supposed to be a no-op.
1340 And ANSI C seems to specify that the type of the result
1341 should be the const type. */
1342 /* A de-reference of a pointer to const is not a const.
It is valid
1343 to change it via some other pointer. */
1344 TREE_READONLY (ref) = TYPE_READONLY (t);
1345 TREE_SIDE_EFFECTS (ref)
1346 = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) ||
1347 TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
1348 return ref;
The question that I have is whether the reference to TYPE_MAIN_VARIANT(t) at
line #1327 should simply refer to `t'? As I understand the meaning of
TYPE_MAIN_VARIANT(), it is the type `t' with all of its qualifiers stripped.
Is it not the case that if P is a pointer to qualified type T, that *P
should yield T, and not T with the qualifiers stripped?
I did a little investigation, and it seems that other parts of the compiler
mask the use of TYPE_MAIN_VARIANT() above. The semantic checking for '*'
will check TREE_READ_ONLY() for example to see whether *p refers to a
read-only (i. e., "const") value, and TREE_READONLY() is derived directly
from type t's (and not t's main variant) TYPE_READONLY flag, which is in
turn derived from t's TYPE_QUAL_CONST qualifier. Further, the semantics for
the construct &*p look explicity for the
"address of an indirected pointer" sequence and in that circumstance, uses
the type of T (where p is a pointer to an object of type T), rather than
using the (unqualified) type assigned to the expression node built for *p.
In summary, it is probably the case that other parts of the compiler cancel
out, or mask the fact that TYPE_MAIN_VARIANT(t) of t was used, rather than
just `t'. Then again, I might be wrong - this code has been this way since
at least 2.7.2 (I didn't check anything ealier). I'm wondering if there is a
C language rule that would dictate that *P should result in a value that has
the type T with qualifiers removed? Or should the resulting type simply be
T? If the latter, then line 1326 above should not refer to
TYPE_MAIN_VARIANT() and should read:
register tree ref = build1 (INDIRECT_REF, t pointer);