[qfcc] Add a failing test for aliased live vars

I'm not sure if it's due more to doubles or unions, but the bug was
found via double. It seems the dags code generator doesn't see that the
assignment to the union's double field kills the two int fields.

The test passes when NOT optimizing.
This commit is contained in:
Bill Currie 2020-04-01 13:45:22 +09:00
parent 7f86fb5529
commit 842125faf8
2 changed files with 51 additions and 0 deletions

View file

@ -43,6 +43,7 @@ test_progs_dat=\
compound.dat \ compound.dat \
deadbool.dat \ deadbool.dat \
double.dat \ double.dat \
double-alias.dat \
enum.dat \ enum.dat \
fordecl.dat \ fordecl.dat \
func-expr.dat \ func-expr.dat \
@ -209,6 +210,15 @@ double.run: Makefile build-run
include ./$(DEPDIR)/double.Qo # am--include-marker include ./$(DEPDIR)/double.Qo # am--include-marker
r_depfiles_remade += ./$(DEPDIR)/double.Qo r_depfiles_remade += ./$(DEPDIR)/double.Qo
double_alias_dat_SOURCES=double-alias.r
double_alias_obj=$(double_alias_dat_SOURCES:.r=.qfo)
double-alias.dat$(EXEEXT): $(double_alias_obj) $(QFCC_DEP)
$(QFCC) $(QCFLAGS) -o $@ $(double_alias_obj)
double-alias.run: Makefile build-run
@$(srcdir)/build-run $@
include ./$(DEPDIR)/double-alias.Qo # am--include-marker
r_depfiles_remade += ./$(DEPDIR)/double-alias.Qo
classarray.run$(EXEEXT): classarray.r Makefile build-compile-fail-run classarray.run$(EXEEXT): classarray.r Makefile build-compile-fail-run
@$(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< @$(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $<

View file

@ -0,0 +1,41 @@
void printf (string fmt, ...) = #0;
# define M_PI 3.14159265358979323846
union {
double d;
int i[2];
} type_pun;
int alias_printf (string fmt, ...);
int
test_alias ()
{
int fail = 0;
type_pun.d = M_PI;
fail = alias_printf ("%g %08x%08x\n", type_pun.d,
type_pun.i[1], type_pun.i[0]);
return fail;
}
int
alias_printf (string fmt, ...)
{
int fail = 0;
// this will fail on big-endian systems
fail = (@args.list[2].integer_val != 0x54442d18
|| @args.list[1].integer_val != 0x400921fb);
printf ("%g %08x%08x\n",
@args.list[0].integer_val,
@args.list[2].integer_val,
@args.list[1].integer_val);
return fail;
}
int
main ()
{
int fail = 0;
fail |= test_alias ();
return fail;
}