summaryrefslogtreecommitdiff
path: root/libgo/go/cmd/vet/testdata/bool.go
blob: 80c44d25ca38890e06e1c0933d6fd67007b48868 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains tests for the bool checker.

package testdata

import "io"

type T int

func (t T) Foo() int { return int(t) }

type FT func() int

var S []int

func RatherStupidConditions() {
	var f, g func() int
	if f() == 0 || f() == 0 { // OK f might have side effects
	}
	var t T
	_ = t.Foo() == 2 || t.Foo() == 2        // OK Foo might have side effects
	if v, w := f(), g(); v == w || v == w { // ERROR "redundant or: v == w || v == w"
	}
	_ = f == nil || f == nil // ERROR "redundant or: f == nil || f == nil"

	_ = i == byte(1) || i == byte(1) // ERROR "redundant or: i == byte(1) || i == byte(1)"
	_ = i == T(2) || i == T(2)       // ERROR "redundant or: i == T(2) || i == T(2)"
	_ = FT(f) == nil || FT(f) == nil // ERROR "redundant or: FT(f) == nil || FT(f) == nil"

	_ = (func() int)(f) == nil || (func() int)(f) == nil // ERROR "redundant or: (func() int)(f) == nil || (func() int)(f) == nil"
	_ = append(S, 3) == nil || append(S, 3) == nil       // OK append has side effects

	var namedFuncVar FT
	_ = namedFuncVar() == namedFuncVar() // OK still func calls

	var c chan int
	_ = 0 == <-c || 0 == <-c                                  // OK subsequent receives may yield different values
	for i, j := <-c, <-c; i == j || i == j; i, j = <-c, <-c { // ERROR "redundant or: i == j || i == j"
	}

	var i, j, k int
	_ = i+1 == 1 || i+1 == 1         // ERROR "redundant or: i\+1 == 1 || i\+1 == 1"
	_ = i == 1 || j+1 == i || i == 1 // ERROR "redundant or: i == 1 || i == 1"

	_ = i == 1 || i == 1 || f() == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || f() == 1 || i == 1 // OK f may alter i as a side effect
	_ = f() == 1 || i == 1 || i == 1 // ERROR "redundant or: i == 1 || i == 1"

	// Test partition edge cases
	_ = f() == 1 || i == 1 || i == 1 || j == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = f() == 1 || j == 1 || i == 1 || i == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || f() == 1 || i == 1 || i == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || i == 1 || f() == 1 || i == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || i == 1 || j == 1 || f() == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = j == 1 || i == 1 || i == 1 || f() == 1 // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || f() == 1 || f() == 1 || i == 1

	_ = i == 1 || (i == 1 || i == 2)             // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || (f() == 1 || i == 1)           // OK f may alter i as a side effect
	_ = i == 1 || (i == 1 || f() == 1)           // ERROR "redundant or: i == 1 || i == 1"
	_ = i == 1 || (i == 2 || (i == 1 || i == 3)) // ERROR "redundant or: i == 1 || i == 1"

	var a, b bool
	_ = i == 1 || (a || (i == 1 || b)) // ERROR "redundant or: i == 1 || i == 1"

	// Check that all redundant ors are flagged
	_ = j == 0 ||
		i == 1 ||
		f() == 1 ||
		j == 0 || // ERROR "redundant or: j == 0 || j == 0"
		i == 1 || // ERROR "redundant or: i == 1 || i == 1"
		i == 1 || // ERROR "redundant or: i == 1 || i == 1"
		i == 1 ||
		j == 0 ||
		k == 0

	_ = i == 1*2*3 || i == 1*2*3 // ERROR "redundant or: i == 1\*2\*3 || i == 1\*2\*3"

	// These test that redundant, suspect expressions do not trigger multiple errors.
	_ = i != 0 || i != 0 // ERROR "redundant or: i != 0 || i != 0"
	_ = i == 0 && i == 0 // ERROR "redundant and: i == 0 && i == 0"

	// and is dual to or; check the basics and
	// let the or tests pull the rest of the weight.
	_ = 0 != <-c && 0 != <-c         // OK subsequent receives may yield different values
	_ = f() != 0 && f() != 0         // OK f might have side effects
	_ = f != nil && f != nil         // ERROR "redundant and: f != nil && f != nil"
	_ = i != 1 && i != 1 && f() != 1 // ERROR "redundant and: i != 1 && i != 1"
	_ = i != 1 && f() != 1 && i != 1 // OK f may alter i as a side effect
	_ = f() != 1 && i != 1 && i != 1 // ERROR "redundant and: i != 1 && i != 1"
}

func RoyallySuspectConditions() {
	var i, j int

	_ = i == 0 || i == 1 // OK
	_ = i != 0 || i != 1 // ERROR "suspect or: i != 0 || i != 1"
	_ = i != 0 || 1 != i // ERROR "suspect or: i != 0 || 1 != i"
	_ = 0 != i || 1 != i // ERROR "suspect or: 0 != i || 1 != i"
	_ = 0 != i || i != 1 // ERROR "suspect or: 0 != i || i != 1"

	_ = (0 != i) || i != 1 // ERROR "suspect or: 0 != i || i != 1"

	_ = i+3 != 7 || j+5 == 0 || i+3 != 9 // ERROR "suspect or: i\+3 != 7 || i\+3 != 9"

	_ = i != 0 || j == 0 || i != 1 // ERROR "suspect or: i != 0 || i != 1"

	_ = i != 0 || i != 1<<4 // ERROR "suspect or: i != 0 || i != 1<<4"

	_ = i != 0 || j != 0
	_ = 0 != i || 0 != j

	var s string
	_ = s != "one" || s != "the other" // ERROR "suspect or: s != .one. || s != .the other."

	_ = "et" != "alii" || "et" != "cetera"         // ERROR "suspect or: .et. != .alii. || .et. != .cetera."
	_ = "me gustas" != "tu" || "le gustas" != "tu" // OK we could catch this case, but it's not worth the code

	var err error
	_ = err != nil || err != io.EOF // TODO catch this case?

	// Sanity check and.
	_ = i != 0 && i != 1 // OK
	_ = i == 0 && i == 1 // ERROR "suspect and: i == 0 && i == 1"
	_ = i == 0 && 1 == i // ERROR "suspect and: i == 0 && 1 == i"
	_ = 0 == i && 1 == i // ERROR "suspect and: 0 == i && 1 == i"
	_ = 0 == i && i == 1 // ERROR "suspect and: 0 == i && i == 1"
}