//+build ignore package main // This file is the input to TestValueForExpr in source_test.go, which // ensures that each expression e immediately following a /*@kind*/(x) // annotation, when passed to Function.ValueForExpr(e), returns a // non-nil Value of the same type as e and of kind 'kind'. func f(spilled, unspilled int) { _ = /*@Load*/ (spilled) _ = /*@Parameter*/ (unspilled) _ = /*@nil*/ (1 + 2) // (constant) i := 0 f := func() (int, int) { return 0, 0 } (print( /*@BinOp*/ (i + 1))) _, _ = /*@Call*/ (f()) ch := /*@MakeChan*/ (make(chan int)) /*@Recv*/ (<-ch) x := /*@Recv*/ (<-ch) _ = x select { case /*@Extract*/ (<-ch): case x := /*@Extract*/ (<-ch): _ = x } defer /*@Function*/ (func() { })() go /*@Function*/ (func() { })() y := 0 if true && /*@BinOp*/ (bool(y > 0)) { y = 1 } _ = /*@Phi*/ (y) map1 := /*@MakeMap*/ (make(map[string]string)) _ = map1 _ = /*@Slice*/ (make([]int, 0)) _ = /*@MakeClosure*/ (func() { print(spilled) }) sl := []int{} _ = /*@Slice*/ (sl[:0]) _ = /*@Alloc*/ (new(int)) tmp := /*@Alloc*/ (new(int)) _ = tmp var iface interface{} _ = /*@TypeAssert*/ (iface.(int)) _ = /*@Load*/ (sl[0]) _ = /*@IndexAddr*/ (&sl[0]) _ = /*@Index*/ ([2]int{}[0]) var p *int _ = /*@Load*/ (*p) _ = /*@Load*/ (global) /*@Load*/ (global)[""] = "" /*@Global*/ (global) = map[string]string{} var local t /*UnOp*/ (local.x) = 1 // Exercise corner-cases of lvalues vs rvalues. type N *N var n N /*@Load*/ (n) = /*@Load*/ (n) /*@ChangeType*/ (n) = /*@Alloc*/ (&n) /*@Load*/ (n) = /*@Load*/ (*n) /*@Load*/ (n) = /*@Load*/ (**n) } func complit() { // Composite literals. // We get different results for // - composite literal as value (e.g. operand to print) // - composite literal initializer for addressable value // - composite literal value assigned to blank var // 1. Slices print( /*@Slice*/ ([]int{})) print( /*@Alloc*/ (&[]int{})) print(& /*@Slice*/ ([]int{})) sl1 := /*@Slice*/ ([]int{}) sl2 := /*@Alloc*/ (&[]int{}) sl3 := & /*@Slice*/ ([]int{}) _, _, _ = sl1, sl2, sl3 _ = /*@Slice*/ ([]int{}) _ = /*@Alloc*/ (& /*@Slice*/ ([]int{})) _ = & /*@Slice*/ ([]int{}) // 2. Arrays print( /*@Load*/ ([1]int{})) print( /*@Alloc*/ (&[1]int{})) print(& /*@Alloc*/ ([1]int{})) arr1 := /*@Alloc*/ ([1]int{}) arr2 := /*@Alloc*/ (&[1]int{}) arr3 := & /*@Alloc*/ ([1]int{}) _, _, _ = arr1, arr2, arr3 _ = /*@Load*/ ([1]int{}) _ = /*@Alloc*/ (& /*@Alloc*/ ([1]int{})) _ = & /*@Alloc*/ ([1]int{}) // 3. Maps type M map[int]int print( /*@MakeMap*/ (M{})) print( /*@Alloc*/ (&M{})) print(& /*@MakeMap*/ (M{})) m1 := /*@MakeMap*/ (M{}) m2 := /*@Alloc*/ (&M{}) m3 := & /*@MakeMap*/ (M{}) _, _, _ = m1, m2, m3 _ = /*@MakeMap*/ (M{}) _ = /*@Alloc*/ (& /*@MakeMap*/ (M{})) _ = & /*@MakeMap*/ (M{}) // 4. Structs print( /*@Load*/ (struct{}{})) print( /*@Alloc*/ (&struct{}{})) print(& /*@Alloc*/ (struct{}{})) s1 := /*@Alloc*/ (struct{}{}) s2 := /*@Alloc*/ (&struct{}{}) s3 := & /*@Alloc*/ (struct{}{}) _, _, _ = s1, s2, s3 _ = /*@Load*/ (struct{}{}) _ = /*@Alloc*/ (& /*@Alloc*/ (struct{}{})) _ = & /*@Alloc*/ (struct{}{}) } type t struct{ x int } // Ensure we can locate methods of named types. func (t) f(param int) { _ = /*@Parameter*/ (param) } // Ensure we can locate init functions. func init() { m := /*@MakeMap*/ (make(map[string]string)) _ = m } // Ensure we can locate variables in initializer expressions. var global = /*@MakeMap*/ (make(map[string]string))