SET_SVAL only uses one, though, the fast_svalue pointer.
It is however true that reading from the argument passed after the set might be optimized by gcc, I guess. Although that seems like a rather odd optimization to do since the relevant code is right there.
Anyway, using an union is not an option since that would require all code that directly reads type/subtype to change.
Interrestingly enough clang on my mac and all other compilers accessible thorough gcc.godbolt.org does not warn about SET_SVAL instances, nor does it produce non-working code.
Could you give this version of SET_SVAL a try, perhaps?
#define SET_SVAL(SVAL, TYPE, SUBTYPE, FIELD, EXPR) do { \ /* Set the type afterwards to avoid a clobbered \ * svalue in case EXPR throws. */ \ struct svalue * _sv_ptr=&( SVAL ); \ _sv_ptr->u.FIELD = (EXPR); \ *((ptrdiff_t*)&_sv_ptr->type) = TYPE_SUBTYPE(TYPE,SUBTYPE);\ } while(0)