Message ID | 51FC06CF.8080300@redhat.com |
---|---|
State | New |
Headers | show |
On Fri, 2 Aug 2013, Andrew MacLeod wrote: > The atomic expression patch works on many cases, but falls short with any kind > of complexity on the RHS of an expression which needs to be mapped to an > atomic_load. Whilst parsing, we cant tell, and the rhs tends to become an > expression before we really know. so In the comments I have my proposed > solution which I will look at when I return in 2 weeks. > Basically, rather than have the ATOMIC_TYPE attribute ripple all the way > through an expression, as soon as we see an ATOMIC_TYPE, we wrap it in a new > node ATOMIC_EXPR, which holds the atomic expression, and sets it own > expression type to the non-atomic variant. This means the only expressions > which will have the TYPE_ATOMIC flag set will be ones which are wrapped in > ATOMIC_EXPR, and those are the ones where we need to go and replace with an > __atomic_load or whatever. My understanding is that the issue here about loads applies exactly when an atomic lvalue is converted to an rvalue. Thus, this should be handled not when the expression is parsed (it might after all be used as an operand of sizeof, unary &, increment, decrement or assignment operators, on the LHS of ".", or in some other GNU C cases such as __real__ and __imag__) but when the lvalue is converted to an rvalue. Unfortunately there isn't a single well-defined place in the C front end at present that does such a conversion (and for non-atomics, it's not clear that e.g. inserting conversions to remove type qualifiers would be particularly useful). There are calls to mark_exp_read in many relevant places, but that's not exactly the same (and, similarly, calls to default_function_array_conversion or default_function_array_read_conversion in some such places). So I think you simply need to go through everywhere an expression appears in the syntax and make sure that if the context indicates lvalue-to-rvalue conversion happens, then a function that carries out such conversion (for the case of atomics) gets called. Certainly it doesn't seem right to set the type of a containing expression to the non-atomic type immediately, given that lvalue conversion does not occur for operands of sizeof, and an atomic type may have a different type from the non-atomic variant. So sizeof applied to an atomic lvalue needs to have the size of the atomic type. A more ambiguous case is what happens with a cast to atomic type, or function returning atomic type, if the result is immediately passed to sizeof (and the atomic type has a different size from the non-atomic type). This is related to DR#423; I'll raise it with WG14. > Ive included an additional 2 line patch which should change the meaning of > __typeof__ (again untested, the joys of imminently leaving for 2 weeks :-). > Im not sure the normal practical uses of > __typeof__ have much meaning for an atomic type, it seems far more useful to > have __typeof__ for an atomic qualified type to return the non-atomic variant. What typeof should do in general for qualified types is unclear (especially in the case of rvalues, where the movement in ISO C seems to be to say that rvalues can't have qualified types at all) - returning the non-atomic type seems reasonable to me.
* cp/parser.c (cp_parser_simple_type_specifier): Change TYPEOF for atomic types to return the non-atomic type. Index: gcc/cp/parser.c =================================================================== *** gcc/cp/parser.c (revision 201248) --- gcc/cp/parser.c (working copy) *************** cp_parser_simple_type_specifier (cp_pars *** 14262,14267 **** --- 14262,14269 ---- /* If it is not already a TYPE, take its type. */ if (!TYPE_P (type)) type = finish_typeof (type); + if (TYPE_ATOMIC (type)) + type = TYPE_MAIN_VARIANT (type); if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type,