summaryrefslogtreecommitdiff
path: root/awkgram.y
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2021-04-14 17:33:07 +0300
committerArnold D. Robbins <arnold@skeeve.com>2021-04-14 17:33:07 +0300
commita8f16ebdef4e43fcda9a4956e8ef528c33728047 (patch)
tree20c7b903104970098337a1f322c8b05ed2c67ece /awkgram.y
parentf271311ac33d44e68da147a273847c3ce8552bb8 (diff)
downloadgawk-a8f16ebdef4e43fcda9a4956e8ef528c33728047.tar.gz
Fixes for lint check of no effect.
Diffstat (limited to 'awkgram.y')
-rw-r--r--awkgram.y36
1 files changed, 27 insertions, 9 deletions
diff --git a/awkgram.y b/awkgram.y
index 6dfbe7e0..e4c9708d 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -5343,6 +5343,16 @@ isnoeffect(OPCODE type)
case Op_not:
case Op_in_array:
return true;
+ // Additional opcodes that can be part of an expression
+ // that has no effect:
+ case Op_and:
+ case Op_or:
+ case Op_push:
+ case Op_push_i:
+ case Op_push_array:
+ case Op_pop:
+ case Op_lint_plus:
+ return true;
default:
break; /* keeps gcc -Wall happy */
}
@@ -6156,6 +6166,7 @@ add_lint(INSTRUCTION *list, LINTTYPE linttype)
{
#ifndef NO_LINT
INSTRUCTION *ip;
+ bool no_effect = true;
switch (linttype) {
case LINT_assign_in_cond:
@@ -6176,26 +6187,33 @@ add_lint(INSTRUCTION *list, LINTTYPE linttype)
if (list->lasti->opcode == Op_pop && list->nexti != list->lasti) {
int line = 0;
- // Get down to the last instruction (FIXME: why?)
+ // Get down to the last instruction ...
for (ip = list->nexti; ip->nexti != list->lasti; ip = ip->nexti) {
- // along the way track line numbers, we will use the line
+ // ... along the way track line numbers, we will use the line
// closest to the opcode if that opcode doesn't have one
if (ip->source_line != 0)
line = ip->source_line;
+
+ // And check each opcode for no effect
+ no_effect = no_effect && isnoeffect(ip->opcode);
}
- if (do_lint) { /* compile-time warning */
- if (isnoeffect(ip->opcode)) {
+ // check the last one also
+ no_effect = no_effect && isnoeffect(ip->opcode);
+
+ // Only if all the traversed opcodes have no effect do we
+ // produce a warning. This avoids warnings for things like
+ // a == b && b = c.
+ if (do_lint) { /* parse-time warning */
+ if (no_effect) {
if (ip->source_line != 0)
line = ip->source_line;
- lintwarn_ln(line, ("statement may have no effect"));
+ lintwarn_ln(line, _("statement has no effect"));
}
}
- if (ip->opcode == Op_push || ip->opcode == Op_push_i) { /* run-time warning */
- list_append(list, instruction(Op_lint));
- list->lasti->lint_type = linttype;
- }
+ // We no longer place a run-time warning also. One warning
+ // at parse time is enough.
}
break;