Ricardo FERNANDEZ PASCUAL writes: > Andrew Haley wrote: > > >Ricardo FERNANDEZ PASCUAL writes: > > > So, I think the real question is: are COMPONENT_REF nodes allowed > > > to be marked as volatile by themselves? I think they should, and > > > actually it seems to work (the generated code looks correct). > > > >volatile is a type qualifier. The type of a COMPONENT_REF is the type > >of the operand to which it refers. If you want to change the > >effective type of a reference, you should generate a suitable > >CONVERT_EXPR. Like this: > > > > tree exp_type = TREE_TYPE (exp); > > tree v_type > > = build_qualified_type (exp_type, > > TYPE_QUALS (exp_type) | TYPE_QUAL_VOLATILE); > > tree addr = build_fold_addr_expr (exp); > > v_type = build_pointer_type (v_type); > > addr = fold_convert (v_type, addr); > > exp = build_fold_indirect_ref (addr); > > > > > Thank you. I have tried this and it works for stores, but not for loads > (for loads it behaves as a non volatile load). > > I have done some experiments to try to understand what is happening, and > I am a bit confused by the bahavior of GCC. Consider the following C > function: > > static struct { int w; } s; > > void wait (void) { > int t; > loop: > t = *((volatile int *) &s.w); > if (t > 0) goto loop; > } > > > The code generated by "cc1 -O3" on x86 is: > > wait: > movl s, %eax > pushl %ebp > movl %esp, %ebp > testl %eax, %eax > jg .L6 > popl %ebp > ret > .L3: > .L6: > jmp .L6 > > > Which does not seem to respect the semantics of volatile. Is this the > expected behavior or is this a bug?
I think it's a bug. The gimple is: wait () { int t; void loop = <<< error >>>; loop:; t = s.w; if (t > 0) { goto loop; } else { } } Whereas for this: > FWIW, the folowing function: > > void wait2 (void) { > int t; > volatile int *p = &s.w; > loop: > t = *p; > if (t > 0) goto loop; > } the gimple is: wait2 () { int t; volatile int * p; void loop = <<< error >>>; p = (volatile int *) &s.w; loop:; t = *p; if (t > 0) { goto loop; } else { } } which looks right. A temporary shouldn't make any difference here. At a wild guess, maybe strip_useless_type_conversions() is doing something Bad. Andrew.