modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/prove.go (about)

     1  // +build amd64
     2  // errorcheck -0 -d=ssa/prove/debug=1
     3  
     4  // Copyright 2016 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  package main
     9  
    10  import "math"
    11  
    12  func f0(a []int) int {
    13  	a[0] = 1
    14  	a[0] = 1 // ERROR "Proved boolean IsInBounds$"
    15  	a[6] = 1
    16  	a[6] = 1 // ERROR "Proved boolean IsInBounds$"
    17  	a[5] = 1 // ERROR "Proved IsInBounds$"
    18  	a[5] = 1 // ERROR "Proved boolean IsInBounds$"
    19  	return 13
    20  }
    21  
    22  func f1(a []int) int {
    23  	if len(a) <= 5 {
    24  		return 18
    25  	}
    26  	a[0] = 1 // ERROR "Proved non-negative bounds IsInBounds$"
    27  	a[0] = 1 // ERROR "Proved boolean IsInBounds$"
    28  	a[6] = 1
    29  	a[6] = 1 // ERROR "Proved boolean IsInBounds$"
    30  	a[5] = 1 // ERROR "Proved IsInBounds$"
    31  	a[5] = 1 // ERROR "Proved boolean IsInBounds$"
    32  	return 26
    33  }
    34  
    35  func f1b(a []int, i int, j uint) int {
    36  	if i >= 0 && i < len(a) {
    37  		return a[i] // ERROR "Proved non-negative bounds IsInBounds$"
    38  	}
    39  	if i >= 10 && i < len(a) {
    40  		return a[i] // ERROR "Proved non-negative bounds IsInBounds$"
    41  	}
    42  	if i >= 10 && i < len(a) {
    43  		return a[i] // ERROR "Proved non-negative bounds IsInBounds$"
    44  	}
    45  	if i >= 10 && i < len(a) { // todo: handle this case
    46  		return a[i-10]
    47  	}
    48  	if j < uint(len(a)) {
    49  		return a[j] // ERROR "Proved IsInBounds$"
    50  	}
    51  	return 0
    52  }
    53  
    54  func f1c(a []int, i int64) int {
    55  	c := uint64(math.MaxInt64 + 10) // overflows int
    56  	d := int64(c)
    57  	if i >= d && i < int64(len(a)) {
    58  		// d overflows, should not be handled.
    59  		return a[i]
    60  	}
    61  	return 0
    62  }
    63  
    64  func f2(a []int) int {
    65  	for i := range a {
    66  		a[i+1] = i
    67  		a[i+1] = i // ERROR "Proved boolean IsInBounds$"
    68  	}
    69  	return 34
    70  }
    71  
    72  func f3(a []uint) int {
    73  	for i := uint(0); i < uint(len(a)); i++ {
    74  		a[i] = i // ERROR "Proved IsInBounds$"
    75  	}
    76  	return 41
    77  }
    78  
    79  func f4a(a, b, c int) int {
    80  	if a < b {
    81  		if a == b { // ERROR "Disproved Eq64$"
    82  			return 47
    83  		}
    84  		if a > b { // ERROR "Disproved Greater64$"
    85  			return 50
    86  		}
    87  		if a < b { // ERROR "Proved boolean Less64$"
    88  			return 53
    89  		}
    90  		if a == b { // ERROR "Disproved boolean Eq64$"
    91  			return 56
    92  		}
    93  		if a > b { // ERROR "Disproved boolean Greater64$"
    94  			return 59
    95  		}
    96  		return 61
    97  	}
    98  	return 63
    99  }
   100  
   101  func f4b(a, b, c int) int {
   102  	if a <= b {
   103  		if a >= b {
   104  			if a == b { // ERROR "Proved Eq64$"
   105  				return 70
   106  			}
   107  			return 75
   108  		}
   109  		return 77
   110  	}
   111  	return 79
   112  }
   113  
   114  func f4c(a, b, c int) int {
   115  	if a <= b {
   116  		if a >= b {
   117  			if a != b { // ERROR "Disproved Neq64$"
   118  				return 73
   119  			}
   120  			return 75
   121  		}
   122  		return 77
   123  	}
   124  	return 79
   125  }
   126  
   127  func f4d(a, b, c int) int {
   128  	if a < b {
   129  		if a < c {
   130  			if a < b { // ERROR "Proved boolean Less64$"
   131  				if a < c { // ERROR "Proved boolean Less64$"
   132  					return 87
   133  				}
   134  				return 89
   135  			}
   136  			return 91
   137  		}
   138  		return 93
   139  	}
   140  	return 95
   141  }
   142  
   143  func f4e(a, b, c int) int {
   144  	if a < b {
   145  		if b > a { // ERROR "Proved Greater64$"
   146  			return 101
   147  		}
   148  		return 103
   149  	}
   150  	return 105
   151  }
   152  
   153  func f4f(a, b, c int) int {
   154  	if a <= b {
   155  		if b > a {
   156  			if b == a { // ERROR "Disproved Eq64$"
   157  				return 112
   158  			}
   159  			return 114
   160  		}
   161  		if b >= a { // ERROR "Proved Geq64$"
   162  			if b == a { // ERROR "Proved Eq64$"
   163  				return 118
   164  			}
   165  			return 120
   166  		}
   167  		return 122
   168  	}
   169  	return 124
   170  }
   171  
   172  func f5(a, b uint) int {
   173  	if a == b {
   174  		if a <= b { // ERROR "Proved Leq64U$"
   175  			return 130
   176  		}
   177  		return 132
   178  	}
   179  	return 134
   180  }
   181  
   182  // These comparisons are compile time constants.
   183  func f6a(a uint8) int {
   184  	if a < a { // ERROR "Disproved Less8U$"
   185  		return 140
   186  	}
   187  	return 151
   188  }
   189  
   190  func f6b(a uint8) int {
   191  	if a < a { // ERROR "Disproved Less8U$"
   192  		return 140
   193  	}
   194  	return 151
   195  }
   196  
   197  func f6x(a uint8) int {
   198  	if a > a { // ERROR "Disproved Greater8U$"
   199  		return 143
   200  	}
   201  	return 151
   202  }
   203  
   204  func f6d(a uint8) int {
   205  	if a <= a { // ERROR "Proved Leq8U$"
   206  		return 146
   207  	}
   208  	return 151
   209  }
   210  
   211  func f6e(a uint8) int {
   212  	if a >= a { // ERROR "Proved Geq8U$"
   213  		return 149
   214  	}
   215  	return 151
   216  }
   217  
   218  func f7(a []int, b int) int {
   219  	if b < len(a) {
   220  		a[b] = 3
   221  		if b < len(a) { // ERROR "Proved boolean Less64$"
   222  			a[b] = 5 // ERROR "Proved boolean IsInBounds$"
   223  		}
   224  	}
   225  	return 161
   226  }
   227  
   228  func f8(a, b uint) int {
   229  	if a == b {
   230  		return 166
   231  	}
   232  	if a > b {
   233  		return 169
   234  	}
   235  	if a < b { // ERROR "Proved Less64U$"
   236  		return 172
   237  	}
   238  	return 174
   239  }
   240  
   241  func f9(a, b bool) int {
   242  	if a {
   243  		return 1
   244  	}
   245  	if a || b { // ERROR "Disproved boolean Arg$"
   246  		return 2
   247  	}
   248  	return 3
   249  }
   250  
   251  func f10(a string) int {
   252  	n := len(a)
   253  	// We optimize comparisons with small constant strings (see cmd/compile/internal/gc/walk.go),
   254  	// so this string literal must be long.
   255  	if a[:n>>1] == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" {
   256  		return 0
   257  	}
   258  	return 1
   259  }
   260  
   261  func f11a(a []int, i int) {
   262  	useInt(a[i])
   263  	useInt(a[i]) // ERROR "Proved boolean IsInBounds$"
   264  }
   265  
   266  func f11b(a []int, i int) {
   267  	useSlice(a[i:])
   268  	useSlice(a[i:]) // ERROR "Proved boolean IsSliceInBounds$"
   269  }
   270  
   271  func f11c(a []int, i int) {
   272  	useSlice(a[:i])
   273  	useSlice(a[:i]) // ERROR "Proved boolean IsSliceInBounds$"
   274  }
   275  
   276  func f11d(a []int, i int) {
   277  	useInt(a[2*i+7])
   278  	useInt(a[2*i+7]) // ERROR "Proved boolean IsInBounds$"
   279  }
   280  
   281  func f12(a []int, b int) {
   282  	useSlice(a[:b])
   283  }
   284  
   285  func f13a(a, b, c int, x bool) int {
   286  	if a > 12 {
   287  		if x {
   288  			if a < 12 { // ERROR "Disproved Less64$"
   289  				return 1
   290  			}
   291  		}
   292  		if x {
   293  			if a <= 12 { // ERROR "Disproved Leq64$"
   294  				return 2
   295  			}
   296  		}
   297  		if x {
   298  			if a == 12 { // ERROR "Disproved Eq64$"
   299  				return 3
   300  			}
   301  		}
   302  		if x {
   303  			if a >= 12 { // ERROR "Proved Geq64$"
   304  				return 4
   305  			}
   306  		}
   307  		if x {
   308  			if a > 12 { // ERROR "Proved boolean Greater64$"
   309  				return 5
   310  			}
   311  		}
   312  		return 6
   313  	}
   314  	return 0
   315  }
   316  
   317  func f13b(a int, x bool) int {
   318  	if a == -9 {
   319  		if x {
   320  			if a < -9 { // ERROR "Disproved Less64$"
   321  				return 7
   322  			}
   323  		}
   324  		if x {
   325  			if a <= -9 { // ERROR "Proved Leq64$"
   326  				return 8
   327  			}
   328  		}
   329  		if x {
   330  			if a == -9 { // ERROR "Proved boolean Eq64$"
   331  				return 9
   332  			}
   333  		}
   334  		if x {
   335  			if a >= -9 { // ERROR "Proved Geq64$"
   336  				return 10
   337  			}
   338  		}
   339  		if x {
   340  			if a > -9 { // ERROR "Disproved Greater64$"
   341  				return 11
   342  			}
   343  		}
   344  		return 12
   345  	}
   346  	return 0
   347  }
   348  
   349  func f13c(a int, x bool) int {
   350  	if a < 90 {
   351  		if x {
   352  			if a < 90 { // ERROR "Proved boolean Less64$"
   353  				return 13
   354  			}
   355  		}
   356  		if x {
   357  			if a <= 90 { // ERROR "Proved Leq64$"
   358  				return 14
   359  			}
   360  		}
   361  		if x {
   362  			if a == 90 { // ERROR "Disproved Eq64$"
   363  				return 15
   364  			}
   365  		}
   366  		if x {
   367  			if a >= 90 { // ERROR "Disproved Geq64$"
   368  				return 16
   369  			}
   370  		}
   371  		if x {
   372  			if a > 90 { // ERROR "Disproved Greater64$"
   373  				return 17
   374  			}
   375  		}
   376  		return 18
   377  	}
   378  	return 0
   379  }
   380  
   381  func f13d(a int) int {
   382  	if a < 5 {
   383  		if a < 9 { // ERROR "Proved Less64$"
   384  			return 1
   385  		}
   386  	}
   387  	return 0
   388  }
   389  
   390  func f13e(a int) int {
   391  	if a > 9 {
   392  		if a > 5 { // ERROR "Proved Greater64$"
   393  			return 1
   394  		}
   395  	}
   396  	return 0
   397  }
   398  
   399  func f13f(a int64) int64 {
   400  	if a > math.MaxInt64 {
   401  		// Unreachable, but prove doesn't know that.
   402  		if a == 0 {
   403  			return 1
   404  		}
   405  	}
   406  	return 0
   407  }
   408  
   409  func f13g(a int) int {
   410  	if a < 3 {
   411  		return 5
   412  	}
   413  	if a > 3 {
   414  		return 6
   415  	}
   416  	if a == 3 { // ERROR "Proved Eq64$"
   417  		return 7
   418  	}
   419  	return 8
   420  }
   421  
   422  func f13h(a int) int {
   423  	if a < 3 {
   424  		if a > 1 {
   425  			if a == 2 { // ERROR "Proved Eq64$"
   426  				return 5
   427  			}
   428  		}
   429  	}
   430  	return 0
   431  }
   432  
   433  func f13i(a uint) int {
   434  	if a == 0 {
   435  		return 1
   436  	}
   437  	if a > 0 { // ERROR "Proved Greater64U$"
   438  		return 2
   439  	}
   440  	return 3
   441  }
   442  
   443  func f14(p, q *int, a []int) {
   444  	// This crazy ordering usually gives i1 the lowest value ID,
   445  	// j the middle value ID, and i2 the highest value ID.
   446  	// That used to confuse CSE because it ordered the args
   447  	// of the two + ops below differently.
   448  	// That in turn foiled bounds check elimination.
   449  	i1 := *p
   450  	j := *q
   451  	i2 := *p
   452  	useInt(a[i1+j])
   453  	useInt(a[i2+j]) // ERROR "Proved boolean IsInBounds$"
   454  }
   455  
   456  func f15(s []int, x int) {
   457  	useSlice(s[x:])
   458  	useSlice(s[:x]) // ERROR "Proved IsSliceInBounds$"
   459  }
   460  
   461  func f16(s []int) []int {
   462  	if len(s) >= 10 {
   463  		return s[:10] // ERROR "Proved non-negative bounds IsSliceInBounds$"
   464  	}
   465  	return nil
   466  }
   467  
   468  //go:noinline
   469  func useInt(a int) {
   470  }
   471  
   472  //go:noinline
   473  func useSlice(a []int) {
   474  }
   475  
   476  func main() {
   477  }