Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/xlint/lint1 lint: add test for "precedence confusion...



details:   https://anonhg.NetBSD.org/src/rev/b617aa11fcf6
branches:  trunk
changeset: 958420:b617aa11fcf6
user:      rillig <rillig%NetBSD.org@localhost>
date:      Mon Jan 04 15:52:51 2021 +0000

description:
lint: add test for "precedence confusion possible [169]"

diffstat:

 tests/usr.bin/xlint/lint1/msg_169.c   |  149 +++++++++++++++++++++++++++++++++-
 tests/usr.bin/xlint/lint1/msg_169.exp |   25 +++++-
 usr.bin/xlint/lint1/tree.c            |   13 ++-
 3 files changed, 181 insertions(+), 6 deletions(-)

diffs (220 lines):

diff -r a55fcbf68600 -r b617aa11fcf6 tests/usr.bin/xlint/lint1/msg_169.c
--- a/tests/usr.bin/xlint/lint1/msg_169.c       Mon Jan 04 15:29:34 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_169.c       Mon Jan 04 15:52:51 2021 +0000
@@ -1,7 +1,150 @@
-/*     $NetBSD: msg_169.c,v 1.1 2021/01/02 10:22:43 rillig Exp $       */
+/*     $NetBSD: msg_169.c,v 1.2 2021/01/04 15:52:51 rillig Exp $       */
 # 3 "msg_169.c"
 
 // Test for message: precedence confusion possible: parenthesize! [169]
 
-TODO: "Add example code that triggers the above message."
-TODO: "Add example code that almost triggers the above message."
+/* lint1-flags: -g -h -S -w */
+
+typedef _Bool bool;
+
+void
+confusing_shift_arith(unsigned a, unsigned b, unsigned c, unsigned char ch)
+{
+       unsigned con, okl, okr;
+
+       con = a + b << c;
+       okl = (a + b) << c;
+       okr = a + (b << c);
+
+       con = a << b + c;
+       okl = (a << b) + c;
+       okr = a << (b + c);
+
+       con = a - b >> c;
+       okl = (a - b) >> c;
+       okr = a - (b >> c);
+
+       con = a >> b - c;
+       okl = (a >> b) - c;
+       okr = a >> (b - c);
+
+       // Parenthesizing the inner operands has no effect on the warning.
+       con = (a) + b << c;
+       con = a + (b) << c;
+       con = a + b << (c);
+
+       // The usual arithmetic promotions have no effect on the warning.
+       con = ch + b << c;
+       con = a + ch << c;
+       con = a + b << ch;
+}
+
+void
+confusing_logical(bool a, bool b, bool c)
+{
+       bool con, okl, okr, eql;
+
+       eql = a && b && c;
+       eql = a || b || c;
+
+       con = a && b || c;
+       okl = (a && b) || c;
+       okr = a && (b || c);
+
+       con = a || b && c;
+       okl = (a || b) && c;
+       okr = a || (b && c);
+}
+
+void
+confusing_bitwise(unsigned a, unsigned b, unsigned c)
+{
+       bool con, okl, okr, eql;
+
+       eql = a & b & c;
+       eql = a | b | c;
+       eql = a ^ b ^ c;
+
+       con = a | b ^ c;
+       okl = (a | b) ^ c;
+       okr = a | (b ^ c);
+
+       con = a | b & c;
+       okl = (a | b) & c;
+       okr = a | (b & c);
+
+       con = a ^ b | c;
+       okl = (a ^ b) | c;
+       okr = a ^ (b | c);
+
+       con = a ^ b & c;
+       okl = (a ^ b) & c;
+       okr = a ^ (b & c);
+
+       con = a & b | c;
+       okl = (a & b) ^ c;
+       okr = a & (b ^ c);
+
+       con = a & b ^ c;
+       okl = (a & b) ^ c;
+       okr = a & (b ^ c);
+
+       con = a & b + c;
+       okl = (a & b) + c;
+       okr = a & (b + c);
+
+       con = a - b | c;
+       okl = (a - b) | c;
+       okr = a - (b | c);
+
+       // This looks like a binomial formula but isn't.
+       con = a ^ 2 - 2 * a * b + b ^ 2;
+
+       // This isn't a binomial formula either since '^' means xor.
+       con = (a ^ 2) - 2 * a * b + (b ^ 2);
+}
+
+void
+constant_expressions(void)
+{
+       unsigned con;
+
+       // The check for confusing precedence happens after constant folding.
+       // Therefore the following lines do not generate warnings.
+       con = 1 & 2 | 3;
+       con = 4 << 5 + 6;
+       con = 7 ^ 8 & 9;
+}
+
+void
+cast_expressions(char a, char b, char c)
+{
+       unsigned con;
+
+       // Adding casts to the leaf nodes doesn't change anything about the
+       // confusing precedence.
+       con = (unsigned)a | (unsigned)b & (unsigned)c;
+       con = (unsigned)a & (unsigned)b | (unsigned)c;
+
+       // Adding a cast around the whole calculation doesn't change the
+       // precedence as well.
+       con = (unsigned)(a | b & c);
+
+       // Adding a cast around an intermediate result groups the operands
+       // of the main node, which prevents any confusion about precedence.
+       con = (unsigned)a | (unsigned)(b & c);
+       con = a | (unsigned)(b & c);
+       con = (unsigned)(a | b) & (unsigned)c;
+       con = (unsigned)(a | b) & c;
+}
+
+void
+expected_precedence(int a, int b, int c)
+{
+       int ok;
+
+       ok = a + b * c;
+}
+
+// TODO: add a test with unsigned long instead of unsigned, to demonstrate
+//  that the typo in
diff -r a55fcbf68600 -r b617aa11fcf6 tests/usr.bin/xlint/lint1/msg_169.exp
--- a/tests/usr.bin/xlint/lint1/msg_169.exp     Mon Jan 04 15:29:34 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_169.exp     Mon Jan 04 15:52:51 2021 +0000
@@ -1,1 +1,24 @@
-msg_169.c(6): syntax error ':' [249]
+msg_169.c(15): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(19): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(23): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(27): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(32): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(33): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(34): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(37): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(38): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(39): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(50): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(54): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(68): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(72): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(76): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(80): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(84): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(88): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(92): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(96): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(101): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(126): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(127): warning: precedence confusion possible: parenthesize! [169]
+msg_169.c(131): warning: precedence confusion possible: parenthesize! [169]
diff -r a55fcbf68600 -r b617aa11fcf6 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c        Mon Jan 04 15:29:34 2021 +0000
+++ b/usr.bin/xlint/lint1/tree.c        Mon Jan 04 15:52:51 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tree.c,v 1.122 2021/01/03 20:38:26 rillig Exp $        */
+/*     $NetBSD: tree.c,v 1.123 2021/01/04 15:52:51 rillig Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.122 2021/01/03 20:38:26 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.123 2021/01/04 15:52:51 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -4001,6 +4001,15 @@
 
        if (mp->m_binary) {
                rparn = 0;
+               /*
+                * FIXME: There is a typo "tn->tn_op == CVT", which should
+                * rather be "rn->tn_op".  Since tn must be a binary operator,
+                * it can never be CVT.
+                *
+                * Before fixing this though, there should be a unit test
+                * that demonstrates an actual change in behavior when this
+                * bug gets fixed.
+                */
                for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left)
                        rparn |= rn->tn_parenthesized;
                rparn |= rn->tn_parenthesized;



Home | Main Index | Thread Index | Old Index