1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // This file contains tests for the bool checker.
13 func (t T
) Foo() int { return int(t
) }
19 func RatherStupidConditions() {
21 if f() == 0 ||
f() == 0 { // OK f might have side effects
24 _
= t
.Foo() == 2 || t
.Foo() == 2 // OK Foo might have side effects
25 if v
, w
:= f(), g(); v
== w || v
== w
{ // ERROR "redundant or: v == w || v == w"
27 _
= f
== nil || f
== nil // ERROR "redundant or: f == nil || f == nil"
29 _
= i
== byte(1) || i
== byte(1) // ERROR "redundant or: i == byte(1) || i == byte(1)"
30 _
= i
== T(2) || i
== T(2) // ERROR "redundant or: i == T(2) || i == T(2)"
31 _
= FT(f
) == nil ||
FT(f
) == nil // ERROR "redundant or: FT(f) == nil || FT(f) == nil"
33 _
= (func() int)(f
) == nil ||
(func() int)(f
) == nil // ERROR "redundant or: (func() int)(f) == nil || (func() int)(f) == nil"
34 _
= append(S
, 3) == nil ||
append(S
, 3) == nil // OK append has side effects
37 _
= namedFuncVar() == namedFuncVar() // OK still func calls
40 _
= 0 == <-c ||
0 == <-c
// OK subsequent receives may yield different values
41 for i
, j
:= <-c
, <-c
; i
== j || i
== j
; i
, j
= <-c
, <-c
{ // ERROR "redundant or: i == j || i == j"
45 _
= i
+1 == 1 || i
+1 == 1 // ERROR "redundant or: i\+1 == 1 || i\+1 == 1"
46 _
= i
== 1 || j
+1 == i || i
== 1 // ERROR "redundant or: i == 1 || i == 1"
48 _
= i
== 1 || i
== 1 ||
f() == 1 // ERROR "redundant or: i == 1 || i == 1"
49 _
= i
== 1 ||
f() == 1 || i
== 1 // OK f may alter i as a side effect
50 _
= f() == 1 || i
== 1 || i
== 1 // ERROR "redundant or: i == 1 || i == 1"
52 // Test partition edge cases
53 _
= f() == 1 || i
== 1 || i
== 1 || j
== 1 // ERROR "redundant or: i == 1 || i == 1"
54 _
= f() == 1 || j
== 1 || i
== 1 || i
== 1 // ERROR "redundant or: i == 1 || i == 1"
55 _
= i
== 1 ||
f() == 1 || i
== 1 || i
== 1 // ERROR "redundant or: i == 1 || i == 1"
56 _
= i
== 1 || i
== 1 ||
f() == 1 || i
== 1 // ERROR "redundant or: i == 1 || i == 1"
57 _
= i
== 1 || i
== 1 || j
== 1 ||
f() == 1 // ERROR "redundant or: i == 1 || i == 1"
58 _
= j
== 1 || i
== 1 || i
== 1 ||
f() == 1 // ERROR "redundant or: i == 1 || i == 1"
59 _
= i
== 1 ||
f() == 1 ||
f() == 1 || i
== 1
61 _
= i
== 1 ||
(i
== 1 || i
== 2) // ERROR "redundant or: i == 1 || i == 1"
62 _
= i
== 1 ||
(f() == 1 || i
== 1) // OK f may alter i as a side effect
63 _
= i
== 1 ||
(i
== 1 ||
f() == 1) // ERROR "redundant or: i == 1 || i == 1"
64 _
= i
== 1 ||
(i
== 2 ||
(i
== 1 || i
== 3)) // ERROR "redundant or: i == 1 || i == 1"
67 _
= i
== 1 ||
(a ||
(i
== 1 || b
)) // ERROR "redundant or: i == 1 || i == 1"
69 // Check that all redundant ors are flagged
73 j
== 0 ||
// ERROR "redundant or: j == 0 || j == 0"
74 i
== 1 ||
// ERROR "redundant or: i == 1 || i == 1"
75 i
== 1 ||
// ERROR "redundant or: i == 1 || i == 1"
80 _
= i
== 1*2*3 || i
== 1*2*3 // ERROR "redundant or: i == 1\*2\*3 || i == 1\*2\*3"
82 // These test that redundant, suspect expressions do not trigger multiple errors.
83 _
= i
!= 0 || i
!= 0 // ERROR "redundant or: i != 0 || i != 0"
84 _
= i
== 0 && i
== 0 // ERROR "redundant and: i == 0 && i == 0"
86 // and is dual to or; check the basics and
87 // let the or tests pull the rest of the weight.
88 _
= 0 != <-c
&& 0 != <-c
// OK subsequent receives may yield different values
89 _
= f() != 0 && f() != 0 // OK f might have side effects
90 _
= f
!= nil && f
!= nil // ERROR "redundant and: f != nil && f != nil"
91 _
= i
!= 1 && i
!= 1 && f() != 1 // ERROR "redundant and: i != 1 && i != 1"
92 _
= i
!= 1 && f() != 1 && i
!= 1 // OK f may alter i as a side effect
93 _
= f() != 1 && i
!= 1 && i
!= 1 // ERROR "redundant and: i != 1 && i != 1"
96 func RoyallySuspectConditions() {
99 _
= i
== 0 || i
== 1 // OK
100 _
= i
!= 0 || i
!= 1 // ERROR "suspect or: i != 0 || i != 1"
101 _
= i
!= 0 ||
1 != i
// ERROR "suspect or: i != 0 || 1 != i"
102 _
= 0 != i ||
1 != i
// ERROR "suspect or: 0 != i || 1 != i"
103 _
= 0 != i || i
!= 1 // ERROR "suspect or: 0 != i || i != 1"
105 _
= (0 != i
) || i
!= 1 // ERROR "suspect or: 0 != i || i != 1"
107 _
= i
+3 != 7 || j
+5 == 0 || i
+3 != 9 // ERROR "suspect or: i\+3 != 7 || i\+3 != 9"
109 _
= i
!= 0 || j
== 0 || i
!= 1 // ERROR "suspect or: i != 0 || i != 1"
111 _
= i
!= 0 || i
!= 1<<4 // ERROR "suspect or: i != 0 || i != 1<<4"
117 _
= s
!= "one" || s
!= "the other" // ERROR "suspect or: s != .one. || s != .the other."
119 _
= "et" != "alii" ||
"et" != "cetera" // ERROR "suspect or: .et. != .alii. || .et. != .cetera."
120 _
= "me gustas" != "tu" ||
"le gustas" != "tu" // OK we could catch this case, but it's not worth the code
123 _
= err
!= nil || err
!= io
.EOF
// TODO catch this case?
126 _
= i
!= 0 && i
!= 1 // OK
127 _
= i
== 0 && i
== 1 // ERROR "suspect and: i == 0 && i == 1"
128 _
= i
== 0 && 1 == i
// ERROR "suspect and: i == 0 && 1 == i"
129 _
= 0 == i
&& 1 == i
// ERROR "suspect and: 0 == i && 1 == i"
130 _
= 0 == i
&& i
== 1 // ERROR "suspect and: 0 == i && i == 1"