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/3d3a88da910a
branches: trunk
changeset: 949187:3d3a88da910a
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 c802f29c5302 -r 3d3a88da910a 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 c802f29c5302 -r 3d3a88da910a 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 c802f29c5302 -r 3d3a88da910a 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