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]
Other format: [Raw text]

'volatile' is propagated into constants and expression nodes (in some cases)?


Given,

     1  volatile int jv;
     2
     3  int main ()
     4  {
     5    ++jv;
     6  }

GCC (development branch, 4.0 and up) creates a tree
node for the expression ++jv that has 'volatile' asserted
in the type associated with the expression:

 <preincrement_expr 0x4026a144
    type <integer_type 0x402f2e04 int volatile public SI
        size <integer_cst 0x402633f0 constant invariant 32>
        unit size <integer_cst 0x40263180 constant invariant 4>
        align 32 symtab 0 alias set -1 precision 32 min <integer_cst
0x402633a8 -2147483648> max <integer_cst 0x402633c0 2147483647>>
    side-effects
    arg 0 <var_decl 0x4026f0b0 jv type <integer_type 0x402f2e04 int>
        side-effects volatile used public static common SI defer-output file
a.c line 1 size <integer_cst 0x402633f0 32> unit size <integer_cst
0x40263180 4>
        align 32>
    arg 1 <integer_cst 0x402fbee8 type <integer_type 0x402f2e04 int>
constant invariant 1>>

Further, 'volatile' is asserted in the type associated with the
integral constant 1, above:

(gdb) pt
 <integer_cst 0x402fbee8 type <integer_type 0x402f2e04 int> constant
invariant 1>
(gdb) p 0x402f2e04
$19 = 1076833796
(gdb) pt
 <integer_type 0x402f2e04 int volatile public SI
    size <integer_cst 0x402633f0 type <integer_type 0x4027205c
bit_size_type> constant invariant 32>
    unit size <integer_cst 0x40263180 type <integer_type 0x40272000 unsigned
int> constant invariant 4>
    align 32 symtab 0 alias set -1 precision 32 min <integer_cst
0x402633a8 -2147483648> max <integer_cst 0x402633c0 2147483647>>

We could argue whether this causes any real harm, because the ISO C
spec. says the following:

===

6.7.3:
The properties associated with qualified types are meaningful only for
expressions that are lvalues.

6.5.16:
The type of an assignment expression is the type of the left operand unless
the left operand has qualified type, in which case it is the unqualified
version of the type of the left operand.

====

And hopefully subsequent passes in the compiler won't be confused
by seeing qualifiers asserted in expression nodes and in constants.

IMO it would be better if the original tree constructed from
the parsed program more closely followed the original source code,
and where possible, removed extraneous qualifiers, unless they
absolutely needed to convey correct semantics.

Above, the qualifiers on expression nodes and constants seem to come
about by a call to convert() from build_unary_op()which works its way
through to this statement in fold_convert():

  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig)
      || lang_hooks.types_compatible_p (TYPE_MAIN_VARIANT (type),
                                        TYPE_MAIN_VARIANT (orig)))
    return fold_build1 (NOP_EXPR, type, arg);

because the main variant types of the qualified "volatile int" and
unqualified "int" are the same, convert() ends up recasting 'arg'
into a qualified (volatile int) type.

I don't know if there are other cases besides pre-/post-
increment that have this problem.  I think it is
also possible that the code in the development head branch
does a better job of generating expression nodes that have
their qualifiers stripped than 4.0 did for example.

Perhaps one way to gain some confidence that all possibilities
have been covered is to add assertions in build_binary_op
and build_unary_op (or build1 and build2 for that matter,
for expression class nodes) that checks that
TYPE_QUALS(t) == TYPE_UNQUALIFIED on expression nodes and
constant nodes (though perhaps TYPE_CONST is meaninful for
certain named constants?).









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