As of commit 7666f806, casting an int to a float fails:
rosuav@sikorsky:~/pike$ bin/pike Pike v8.0 release 3 running Hilfe v3.5 (Incremental Pike Frontend)
(float)1;
Cast failed, wanted float, got int HilfeInput:1: HilfeInput()->___HilfeWrapper()
This happens also on any arithmetic operation that mixes int and float, which does an equivalent cast implicitly. Fiddling around with the corresponding code suggests it may be connected to the GCC warning that also comes up:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
In SET_SVAL, two pointers to the same object with different types are used. I think this violates the C standard, which is why sometimes stuff isn't getting correctly written out - something's getting optimized away. Is there a way to do the same job with a union inside struct svalue, instead of the pointer casts? Or alternatively, can the compiler be told not to optimize this out?
ChrisA
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)
pike-devel@lists.lysator.liu.se