diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | awkgram.c | 6 | ||||
-rw-r--r-- | awkgram.y | 6 | ||||
-rw-r--r-- | builtin.c | 3 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | interpret.h | 9 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/Makefile.in | 9 | ||||
-rw-r--r-- | test/Maketests | 5 | ||||
-rw-r--r-- | test/typeof2.awk | 20 | ||||
-rw-r--r-- | test/typeof2.ok | 6 |
13 files changed, 79 insertions, 9 deletions
@@ -1,3 +1,16 @@ +2015-06-21 Arnold D. Robbins <arnold@skeeve.com> + + Fixes for typeof - Don't let typeof change an untyped variable + into a scalar. + + * awk.h (opcodeval): Add Op_push_arg_untyped. + * awkgram.y (snode): Separate out case for do_typeof, use + Op_push_arg_untyped. + * builtin.c (do_typeof): Arg will be equal to Nnull_string + if it's untyped. + * eval.c (optypes): Add Op_push_arg_untyped. + * interpret.h (r_interpret): Add Op_push_arg_untyped handling. + 2015-06-19 Arnold D. Robbins <arnold@skeeve.com> * builtin.c (do_isarray): Minor edit to lint warning. @@ -643,6 +643,7 @@ typedef enum opcodeval { Op_push, /* scalar variable */ Op_push_arg, /* variable type (scalar or array) argument to built-in */ + Op_push_arg_untyped, /* like Op_push_arg, but for typeof */ Op_push_i, /* number, string */ Op_push_re, /* regex */ Op_push_array, @@ -6697,10 +6697,14 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg; /* argument may be array */ } - } else if (r->builtin == do_isarray || r->builtin == do_typeof) { + } else if (r->builtin == do_isarray) { arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg; /* argument may be array */ + } else if (r->builtin == do_typeof) { + arg = subn->nexti; + if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) + arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR || r->builtin == MPF(intdiv) @@ -4277,10 +4277,14 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg; /* argument may be array */ } - } else if (r->builtin == do_isarray || r->builtin == do_typeof) { + } else if (r->builtin == do_isarray) { arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg; /* argument may be array */ + } else if (r->builtin == do_typeof) { + arg = subn->nexti; + if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) + arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR || r->builtin == MPF(intdiv) @@ -3872,7 +3872,6 @@ do_typeof(int nargs) { NODE *arg; char *res = "unknown"; - int null_str_flags = (STRCUR|STRING|NUMCUR|NUMBER); arg = POP(); switch (arg->type) { @@ -3884,7 +3883,7 @@ do_typeof(int nargs) break; case Node_val: case Node_var: - if ((arg->flags & null_str_flags) == null_str_flags) + if (arg == Nnull_string) res = "untyped"; else if ((arg->flags & STRING) != 0) res = "scalar_s"; @@ -338,6 +338,7 @@ static struct optypetab { { "Op_indirect_func_call", NULL }, { "Op_push", NULL }, { "Op_push_arg", NULL }, + { "Op_push_arg_untyped", NULL }, { "Op_push_i", NULL }, { "Op_push_re", NULL }, { "Op_push_array", NULL }, diff --git a/interpret.h b/interpret.h index 03532f43..554a7663 100644 --- a/interpret.h +++ b/interpret.h @@ -144,6 +144,7 @@ top: case Op_push: case Op_push_arg: + case Op_push_arg_untyped: { NODE *save_symbol; bool isparam = false; @@ -175,8 +176,10 @@ top: case Node_var_new: uninitialized_scalar: - m->type = Node_var; - m->var_value = dupnode(Nnull_string); + if (op != Op_push_arg_untyped) { + m->type = Node_var; + m->var_value = dupnode(Nnull_string); + } if (do_lint) lintwarn(isparam ? _("reference to uninitialized argument `%s'") : @@ -187,7 +190,7 @@ uninitialized_scalar: break; case Node_var_array: - if (op == Op_push_arg) + if (op == Op_push_arg || op == Op_push_arg_untyped) PUSH(m); else fatal(_("attempt to use array `%s' in a scalar context"), diff --git a/test/ChangeLog b/test/ChangeLog index b57a756f..393f38e8 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2015-06-21 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (typeof2): New test. + * typeof2.awk, typeof2.ok: New files. + 2015-06-19 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (gsubind, typedregex1, typeof1): New tests. diff --git a/test/Makefile.am b/test/Makefile.am index 537a5655..25b8b708 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -985,6 +985,8 @@ EXTRA_DIST = \ typedregex1.ok \ typeof1.awk \ typeof1.ok \ + typeof2.awk \ + typeof2.ok \ uninit2.awk \ uninit2.ok \ uninit3.awk \ @@ -1099,7 +1101,7 @@ GAWK_EXT_TESTS = \ splitarg4 strftime \ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ symtab7 symtab8 symtab9 \ - typedregex1 typeof1 + typedregex1 typeof1 typeof2 timeout EXTRA_TESTS = inftest regtest diff --git a/test/Makefile.in b/test/Makefile.in index a8895ed7..1ab60181 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1242,6 +1242,8 @@ EXTRA_DIST = \ typedregex1.ok \ typeof1.awk \ typeof1.ok \ + typeof2.awk \ + typeof2.ok \ uninit2.awk \ uninit2.ok \ uninit3.awk \ @@ -1355,7 +1357,7 @@ GAWK_EXT_TESTS = \ splitarg4 strftime \ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ symtab7 symtab8 symtab9 \ - typedregex1 typeof1 + typedregex1 typeof1 typeof2 EXTRA_TESTS = inftest regtest INET_TESTS = inetdayu inetdayt inetechu inetecht @@ -3905,6 +3907,11 @@ typeof1: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +typeof2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + double1: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index a674d5d0..baf973ec 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1342,6 +1342,11 @@ typeof1: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +typeof2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + double1: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/typeof2.awk b/test/typeof2.awk new file mode 100644 index 00000000..25da02e4 --- /dev/null +++ b/test/typeof2.awk @@ -0,0 +1,20 @@ +BEGIN { + print typeof(x) + x[1] = 3 + print typeof(x) +} + +function test1() { +} + +function test2(p) { + p[1] = 1 +} + +BEGIN { + print typeof(a) + test1(a) + print typeof(a) + test2(a) + print typeof(a) +} diff --git a/test/typeof2.ok b/test/typeof2.ok new file mode 100644 index 00000000..cc032a83 --- /dev/null +++ b/test/typeof2.ok @@ -0,0 +1,6 @@ +untyped +array +untyped +gawk: typeof2.awk:16: warning: function `test1' called with more arguments than declared +untyped +array |