From 6ce99afa5bd7260937a0b74d3cb07fcdc87a8488 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 15 Feb 2020 17:42:46 +0900 Subject: [PATCH] Catch double demotion in global initializers Local initializers are handled by regular assignments --- tools/qfcc/source/def.c | 8 +++++++- tools/qfcc/test/Makefile.am | 8 ++++++++ tools/qfcc/test/double-demote-float-ginit.r | 6 ++++++ tools/qfcc/test/double-demote-int-ginit.r | 6 ++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tools/qfcc/test/double-demote-float-ginit.r create mode 100644 tools/qfcc/test/double-demote-int-ginit.r diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index f7735d8c3..6e545ba40 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -575,7 +575,8 @@ initialize_def (symbol_t *sym, expr_t *init, defspace_t *space, init_elements (sym->s.def, init); sym->s.def->initialized = 1; } else { - if (!type_assignable (sym->type, get_type (init))) { + type_t *init_type = get_type (init); + if (!type_assignable (sym->type, init_type)) { error (init, "type mismatch in initializer"); return; } @@ -609,6 +610,11 @@ initialize_def (symbol_t *sym, expr_t *init, defspace_t *space, reloc_def_field (init->e.value->v.pointer.def, sym->s.def); } else { ex_value_t *v = init->e.value; + if (is_double (init_type) + && (is_integral (sym->type) || is_float (sym->type))) { + warning (init, "assigning double to %s in initializer " + "(use a cast)", sym->type->name); + } if (is_scalar (sym->type)) v = convert_value (v, sym->type); if (v->lltype == ev_string) { diff --git a/tools/qfcc/test/Makefile.am b/tools/qfcc/test/Makefile.am index 1d3d9de9c..748f779c1 100644 --- a/tools/qfcc/test/Makefile.am +++ b/tools/qfcc/test/Makefile.am @@ -62,8 +62,10 @@ fail_progs_dat= test_build_errors=\ double-demote-float.r \ + double-demote-float-ginit.r \ double-demote-float-linit.r \ double-demote-int.r \ + double-demote-int-ginit.r \ double-demote-int-linit.r \ double-int-compare.r \ double-float-compare.r @@ -163,6 +165,12 @@ double-demote-int.run$(EXEEXT): double-demote-int.r Makefile build-compile-fail- double-demote-float.run$(EXEEXT): double-demote-float.r Makefile build-compile-fail-run $(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< +double-demote-int-ginit.run$(EXEEXT): double-demote-int-ginit.r Makefile build-compile-fail-run + $(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< + +double-demote-float-ginit.run$(EXEEXT): double-demote-float-ginit.r Makefile build-compile-fail-run + $(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< + double-demote-int-linit.run$(EXEEXT): double-demote-int-linit.r Makefile build-compile-fail-run $(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< diff --git a/tools/qfcc/test/double-demote-float-ginit.r b/tools/qfcc/test/double-demote-float-ginit.r new file mode 100644 index 000000000..c88b5e987 --- /dev/null +++ b/tools/qfcc/test/double-demote-float-ginit.r @@ -0,0 +1,6 @@ +double a; +float b = 1.0d; +int main () +{ + return 1; // test fails if compile succeeds +} diff --git a/tools/qfcc/test/double-demote-int-ginit.r b/tools/qfcc/test/double-demote-int-ginit.r new file mode 100644 index 000000000..767328715 --- /dev/null +++ b/tools/qfcc/test/double-demote-int-ginit.r @@ -0,0 +1,6 @@ +double a; +int b = 1.0d; +int main () +{ + return 1; // test fails if compile succeeds +}