summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2020-05-06 20:55:07 +0300
committerArnold D. Robbins <arnold@skeeve.com>2020-05-06 20:55:07 +0300
commit1b79c13f8aa4c93ea727b1d42b30f3838faeaedf (patch)
tree97ee08fd0c99777fb1e9a78ca8a3a6bd3e017e94
parent2a1b7457e8c878650352cf4925872c59d07a5fa2 (diff)
downloadgawk-1b79c13f8aa4c93ea727b1d42b30f3838faeaedf.tar.gz
Add lint check for string + string.
-rw-r--r--ChangeLog12
-rw-r--r--awk.h1
-rw-r--r--awkgram.c8
-rw-r--r--awkgram.y8
-rw-r--r--eval.c1
-rw-r--r--interpret.h9
-rw-r--r--pc/Makefile.tst9
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am6
-rw-r--r--test/Makefile.in11
-rw-r--r--test/Maketests5
-rw-r--r--test/lintplus.awk1
-rw-r--r--test/lintplus.ok2
13 files changed, 70 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 1cca95d4..d23a6793 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2020-05-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ Add lint check for string + string. It's not concatenation
+ in awk, but is in most other languages. Thanks to Roland Illig
+ <roland.illig@gmx.de> for the suggestion.
+
+ * awk.h (Op_lint_plus): New opcode.
+ * awkgram.y (mk_binary): Add it into the list in the right place
+ if do_lint.
+ * eval.c (optypes): Add case for Op_lint_plus.
+ * interpret.h (r_interpret): Ditto.
+
2020-04-14 Arnold D. Robbins <arnold@skeeve.com>
* 5.1.0: Release tar ball made.
diff --git a/awk.h b/awk.h
index 70d132f4..3fba240d 100644
--- a/awk.h
+++ b/awk.h
@@ -713,6 +713,7 @@ typedef enum opcodeval {
Op_exec_count,
Op_breakpoint,
Op_lint,
+ Op_lint_plus,
Op_atexit,
Op_stop,
diff --git a/awkgram.c b/awkgram.c
index fa62ee6f..0aa364a4 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -8016,7 +8016,7 @@ dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
static INSTRUCTION *
mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
{
- INSTRUCTION *ip1,*ip2;
+ INSTRUCTION *ip1,*ip2, *lint_plus;
AWKNUM res;
ip2 = s2->nexti;
@@ -8095,6 +8095,8 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
op->opcode = Op_mod_i;
break;
case Op_plus:
+ if (do_lint)
+ goto regular;
op->opcode = Op_plus_i;
break;
case Op_minus:
@@ -8117,6 +8119,10 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
regular:
/* append lists s1, s2 and add `op' bytecode */
(void) list_merge(s1, s2);
+ if (do_lint && op->opcode == Op_plus) {
+ lint_plus = instruction(Op_lint_plus);
+ (void) list_append(s1, lint_plus);
+ }
return list_append(s1, op);
}
diff --git a/awkgram.y b/awkgram.y
index 00333ea0..281d0ef8 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -5429,7 +5429,7 @@ dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
static INSTRUCTION *
mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
{
- INSTRUCTION *ip1,*ip2;
+ INSTRUCTION *ip1,*ip2, *lint_plus;
AWKNUM res;
ip2 = s2->nexti;
@@ -5508,6 +5508,8 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
op->opcode = Op_mod_i;
break;
case Op_plus:
+ if (do_lint)
+ goto regular;
op->opcode = Op_plus_i;
break;
case Op_minus:
@@ -5530,6 +5532,10 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
regular:
/* append lists s1, s2 and add `op' bytecode */
(void) list_merge(s1, s2);
+ if (do_lint && op->opcode == Op_plus) {
+ lint_plus = instruction(Op_lint_plus);
+ (void) list_append(s1, lint_plus);
+ }
return list_append(s1, op);
}
diff --git a/eval.c b/eval.c
index 3a3a2f6b..c6c37b8c 100644
--- a/eval.c
+++ b/eval.c
@@ -369,6 +369,7 @@ static struct optypetab {
{ "Op_exec_count", NULL },
{ "Op_breakpoint", NULL },
{ "Op_lint", NULL },
+ { "Op_lint_plus", NULL },
{ "Op_atexit", NULL },
{ "Op_stop", NULL },
{ "Op_token", NULL },
diff --git a/interpret.h b/interpret.h
index 80ef4689..6137e8e0 100644
--- a/interpret.h
+++ b/interpret.h
@@ -412,6 +412,15 @@ uninitialized_scalar:
}
break;
+ case Op_lint_plus:
+ // no need to check do_lint, this opcode won't
+ // be generated if that's not true
+ t1 = TOP();
+ t2 = PEEK(1);
+ if ((t1->flags & STRING) != 0 && (t2->flags & STRING) != 0)
+ lintwarn(_("operator `+' used on two string values"));
+ break;
+
case Op_K_break:
case Op_K_continue:
case Op_jmp:
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index ac45f499..22ac2240 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -202,7 +202,7 @@ GAWK_EXT_TESTS = \
icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \
incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \
indirectbuiltin indirectcall indirectcall2 intarray isarrayunset \
- lint lintexp lintindex lintint lintlength lintold lintset lintwarn \
+ lint lintexp lintindex lintint lintlength lintplus lintold lintset lintwarn \
manyfiles match1 match2 match3 mbstr1 mbstr2 mixed1 mktime muldimposix \
nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \
nsawk1a nsawk1b nsawk1c nsawk2a nsawk2b \
@@ -249,7 +249,7 @@ NEED_DEBUG = dbugtypedre1 dbugtypedre2 dbugeval2 dbugeval3 symtab10
# List of the tests which should be run with --lint option:
NEED_LINT = \
- defref fmtspcl lintexp lintindex lintint lintlength lintwarn \
+ defref fmtspcl lintexp lintindex lintint lintlength lintplus lintwarn \
noeffect nofmtch nonl shadow uninit2 uninit3 uninit4 uninit5 uninitialized
@@ -2883,6 +2883,11 @@ lintlength:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+lintplus:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
lintold:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint-old < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/ChangeLog b/test/ChangeLog
index 45c65052..097f19bd 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2020-05-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): New test, lintplus.
+ * lintplus.awk, lintplus.ok: New files.
+
2020-04-14 Arnold D. Robbins <arnold@skeeve.com>
* 5.1.0: Release tar ball made.
diff --git a/test/Makefile.am b/test/Makefile.am
index c2ad113c..55b1ff34 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -625,6 +625,8 @@ EXTRA_DIST = \
lintold.awk \
lintold.in \
lintold.ok \
+ lintplus.awk \
+ lintplus.ok \
lintset.awk \
lintset.ok \
lintwarn.awk \
@@ -1396,7 +1398,7 @@ GAWK_EXT_TESTS = \
icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \
incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \
indirectbuiltin indirectcall indirectcall2 intarray isarrayunset \
- lint lintexp lintindex lintint lintlength lintold lintset lintwarn \
+ lint lintexp lintindex lintint lintlength lintplus lintold lintset lintwarn \
manyfiles match1 match2 match3 mbstr1 mbstr2 mixed1 mktime muldimposix \
nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \
nsawk1a nsawk1b nsawk1c nsawk2a nsawk2b \
@@ -1446,7 +1448,7 @@ NEED_DEBUG = dbugtypedre1 dbugtypedre2 dbugeval2 dbugeval3 symtab10
# List of the tests which should be run with --lint option:
NEED_LINT = \
- defref fmtspcl lintexp lintindex lintint lintlength lintwarn \
+ defref fmtspcl lintexp lintindex lintint lintlength lintplus lintwarn \
noeffect nofmtch nonl shadow uninit2 uninit3 uninit4 uninit5 uninitialized
# List of the tests which should be run with --lint-old option:
diff --git a/test/Makefile.in b/test/Makefile.in
index 67051084..f5f8e05a 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -886,6 +886,8 @@ EXTRA_DIST = \
lintold.awk \
lintold.in \
lintold.ok \
+ lintplus.awk \
+ lintplus.ok \
lintset.awk \
lintset.ok \
lintwarn.awk \
@@ -1657,7 +1659,7 @@ GAWK_EXT_TESTS = \
icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \
incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \
indirectbuiltin indirectcall indirectcall2 intarray isarrayunset \
- lint lintexp lintindex lintint lintlength lintold lintset lintwarn \
+ lint lintexp lintindex lintint lintlength lintplus lintold lintset lintwarn \
manyfiles match1 match2 match3 mbstr1 mbstr2 mixed1 mktime muldimposix \
nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \
nsawk1a nsawk1b nsawk1c nsawk2a nsawk2b \
@@ -1704,7 +1706,7 @@ NEED_DEBUG = dbugtypedre1 dbugtypedre2 dbugeval2 dbugeval3 symtab10
# List of the tests which should be run with --lint option:
NEED_LINT = \
- defref fmtspcl lintexp lintindex lintint lintlength lintwarn \
+ defref fmtspcl lintexp lintindex lintint lintlength lintplus lintwarn \
noeffect nofmtch nonl shadow uninit2 uninit3 uninit4 uninit5 uninitialized
@@ -4503,6 +4505,11 @@ lintlength:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+lintplus:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
lintold:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint-old < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index 6982870d..4bee1ddc 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -1637,6 +1637,11 @@ lintlength:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+lintplus:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
lintold:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk --lint-old < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/lintplus.awk b/test/lintplus.awk
new file mode 100644
index 00000000..3c4e76c4
--- /dev/null
+++ b/test/lintplus.awk
@@ -0,0 +1 @@
+BEGIN { y = substr("abc", 2, 2) + "d" ; print y }
diff --git a/test/lintplus.ok b/test/lintplus.ok
new file mode 100644
index 00000000..e03a19ea
--- /dev/null
+++ b/test/lintplus.ok
@@ -0,0 +1,2 @@
+gawk: lintplus.awk:1: warning: operator `+' used on two string values
+0