[dev.boringcrypto] all: merge master into dev.boringcrypto

Add a couple of skips for slow js/wasm tests.

Change-Id: Ic95256b1d3c6e5e2f0cc536fad51e914d31cda9e
This commit is contained in:
Filippo Valsorda 2018-06-29 13:16:42 -04:00
commit 77db076129
627 changed files with 25394 additions and 4409 deletions

2
.github/SUPPORT.md vendored
View file

@ -9,6 +9,6 @@ For asking questions, see:
* [Gophers Slack](https://gophers.slack.com), use the [invite app](https://invite.slack.golangbridge.org/) for access
* [Stack Overflow](http://stackoverflow.com/questions/tagged/go) with questions tagged "go"
* [Stack Overflow](https://stackoverflow.com/questions/tagged/go) with questions tagged "go"
* **IRC** channel #go-nuts on Freenode

View file

@ -362,24 +362,17 @@ pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
pkg syscall (openbsd-amd64), const SYS_KILL = 37
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
pkg unicode, const Version = "9.0.0"
pkg text/template/parse, method (*VariableNode) Copy() Node
pkg text/template/parse, method (*VariableNode) String() string
pkg text/template/parse, method (VariableNode) Position() Pos
pkg text/template/parse, method (VariableNode) Type() NodeType
pkg text/template/parse, type PipeNode struct, Decl []*VariableNode
pkg text/template/parse, type VariableNode struct
pkg text/template/parse, type VariableNode struct, Ident []string
pkg text/template/parse, type VariableNode struct, embedded NodeType
pkg text/template/parse, type VariableNode struct, embedded Pos
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-386), type CertContext struct, CertInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-386), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-386), const TOKEN_ALL_ACCESS = 983295
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-amd64), type CertContext struct, CertInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-amd64), const TOKEN_ALL_ACCESS = 983295

546
api/go1.11.txt Normal file
View file

@ -0,0 +1,546 @@
pkg crypto/cipher, func NewGCMWithTagSize(Block, int) (AEAD, error)
pkg crypto/rsa, method (*PrivateKey) Size() int
pkg crypto/rsa, method (*PublicKey) Size() int
pkg crypto/tls, type ConnectionState struct, ExportKeyingMaterial func(string, []uint8, int) ([]uint8, bool)
pkg database/sql, method (IsolationLevel) String() string
pkg database/sql, type DBStats struct, Idle int
pkg database/sql, type DBStats struct, InUse int
pkg database/sql, type DBStats struct, MaxIdleClosed int64
pkg database/sql, type DBStats struct, MaxLifetimeClosed int64
pkg database/sql, type DBStats struct, MaxOpenConnections int
pkg database/sql, type DBStats struct, WaitCount int64
pkg database/sql, type DBStats struct, WaitDuration time.Duration
pkg debug/elf, const ELFOSABI_AROS = 15
pkg debug/elf, const ELFOSABI_AROS OSABI
pkg debug/elf, const ELFOSABI_CLOUDABI = 17
pkg debug/elf, const ELFOSABI_CLOUDABI OSABI
pkg debug/elf, const ELFOSABI_FENIXOS = 16
pkg debug/elf, const ELFOSABI_FENIXOS OSABI
pkg debug/elf, const EM_56800EX = 200
pkg debug/elf, const EM_56800EX Machine
pkg debug/elf, const EM_68HC05 = 72
pkg debug/elf, const EM_68HC05 Machine
pkg debug/elf, const EM_68HC08 = 71
pkg debug/elf, const EM_68HC08 Machine
pkg debug/elf, const EM_68HC11 = 70
pkg debug/elf, const EM_68HC11 Machine
pkg debug/elf, const EM_68HC16 = 69
pkg debug/elf, const EM_68HC16 Machine
pkg debug/elf, const EM_78KOR = 199
pkg debug/elf, const EM_78KOR Machine
pkg debug/elf, const EM_8051 = 165
pkg debug/elf, const EM_8051 Machine
pkg debug/elf, const EM_ALTERA_NIOS2 = 113
pkg debug/elf, const EM_ALTERA_NIOS2 Machine
pkg debug/elf, const EM_AMDGPU = 224
pkg debug/elf, const EM_AMDGPU Machine
pkg debug/elf, const EM_ARCA = 109
pkg debug/elf, const EM_ARCA Machine
pkg debug/elf, const EM_ARC_COMPACT = 93
pkg debug/elf, const EM_ARC_COMPACT Machine
pkg debug/elf, const EM_ARC_COMPACT2 = 195
pkg debug/elf, const EM_ARC_COMPACT2 Machine
pkg debug/elf, const EM_AVR = 83
pkg debug/elf, const EM_AVR Machine
pkg debug/elf, const EM_AVR32 = 185
pkg debug/elf, const EM_AVR32 Machine
pkg debug/elf, const EM_BA1 = 201
pkg debug/elf, const EM_BA1 Machine
pkg debug/elf, const EM_BA2 = 202
pkg debug/elf, const EM_BA2 Machine
pkg debug/elf, const EM_BLACKFIN = 106
pkg debug/elf, const EM_BLACKFIN Machine
pkg debug/elf, const EM_BPF = 247
pkg debug/elf, const EM_BPF Machine
pkg debug/elf, const EM_C166 = 116
pkg debug/elf, const EM_C166 Machine
pkg debug/elf, const EM_CDP = 215
pkg debug/elf, const EM_CDP Machine
pkg debug/elf, const EM_CE = 119
pkg debug/elf, const EM_CE Machine
pkg debug/elf, const EM_CLOUDSHIELD = 192
pkg debug/elf, const EM_CLOUDSHIELD Machine
pkg debug/elf, const EM_COGE = 216
pkg debug/elf, const EM_COGE Machine
pkg debug/elf, const EM_COOL = 217
pkg debug/elf, const EM_COOL Machine
pkg debug/elf, const EM_COREA_1ST = 193
pkg debug/elf, const EM_COREA_1ST Machine
pkg debug/elf, const EM_COREA_2ND = 194
pkg debug/elf, const EM_COREA_2ND Machine
pkg debug/elf, const EM_CR = 103
pkg debug/elf, const EM_CR Machine
pkg debug/elf, const EM_CR16 = 177
pkg debug/elf, const EM_CR16 Machine
pkg debug/elf, const EM_CRAYNV2 = 172
pkg debug/elf, const EM_CRAYNV2 Machine
pkg debug/elf, const EM_CRIS = 76
pkg debug/elf, const EM_CRIS Machine
pkg debug/elf, const EM_CRX = 114
pkg debug/elf, const EM_CRX Machine
pkg debug/elf, const EM_CSR_KALIMBA = 219
pkg debug/elf, const EM_CSR_KALIMBA Machine
pkg debug/elf, const EM_CUDA = 190
pkg debug/elf, const EM_CUDA Machine
pkg debug/elf, const EM_CYPRESS_M8C = 161
pkg debug/elf, const EM_CYPRESS_M8C Machine
pkg debug/elf, const EM_D10V = 85
pkg debug/elf, const EM_D10V Machine
pkg debug/elf, const EM_D30V = 86
pkg debug/elf, const EM_D30V Machine
pkg debug/elf, const EM_DSP24 = 136
pkg debug/elf, const EM_DSP24 Machine
pkg debug/elf, const EM_DSPIC30F = 118
pkg debug/elf, const EM_DSPIC30F Machine
pkg debug/elf, const EM_DXP = 112
pkg debug/elf, const EM_DXP Machine
pkg debug/elf, const EM_ECOG1 = 168
pkg debug/elf, const EM_ECOG1 Machine
pkg debug/elf, const EM_ECOG16 = 176
pkg debug/elf, const EM_ECOG16 Machine
pkg debug/elf, const EM_ECOG1X = 168
pkg debug/elf, const EM_ECOG1X Machine
pkg debug/elf, const EM_ECOG2 = 134
pkg debug/elf, const EM_ECOG2 Machine
pkg debug/elf, const EM_ETPU = 178
pkg debug/elf, const EM_ETPU Machine
pkg debug/elf, const EM_EXCESS = 111
pkg debug/elf, const EM_EXCESS Machine
pkg debug/elf, const EM_F2MC16 = 104
pkg debug/elf, const EM_F2MC16 Machine
pkg debug/elf, const EM_FIREPATH = 78
pkg debug/elf, const EM_FIREPATH Machine
pkg debug/elf, const EM_FR30 = 84
pkg debug/elf, const EM_FR30 Machine
pkg debug/elf, const EM_FT32 = 222
pkg debug/elf, const EM_FT32 Machine
pkg debug/elf, const EM_FX66 = 66
pkg debug/elf, const EM_FX66 Machine
pkg debug/elf, const EM_HUANY = 81
pkg debug/elf, const EM_HUANY Machine
pkg debug/elf, const EM_INTEL205 = 205
pkg debug/elf, const EM_INTEL205 Machine
pkg debug/elf, const EM_INTEL206 = 206
pkg debug/elf, const EM_INTEL206 Machine
pkg debug/elf, const EM_INTEL207 = 207
pkg debug/elf, const EM_INTEL207 Machine
pkg debug/elf, const EM_INTEL208 = 208
pkg debug/elf, const EM_INTEL208 Machine
pkg debug/elf, const EM_INTEL209 = 209
pkg debug/elf, const EM_INTEL209 Machine
pkg debug/elf, const EM_IP2K = 101
pkg debug/elf, const EM_IP2K Machine
pkg debug/elf, const EM_JAVELIN = 77
pkg debug/elf, const EM_JAVELIN Machine
pkg debug/elf, const EM_K10M = 181
pkg debug/elf, const EM_K10M Machine
pkg debug/elf, const EM_KM32 = 210
pkg debug/elf, const EM_KM32 Machine
pkg debug/elf, const EM_KMX16 = 212
pkg debug/elf, const EM_KMX16 Machine
pkg debug/elf, const EM_KMX32 = 211
pkg debug/elf, const EM_KMX32 Machine
pkg debug/elf, const EM_KMX8 = 213
pkg debug/elf, const EM_KMX8 Machine
pkg debug/elf, const EM_KVARC = 214
pkg debug/elf, const EM_KVARC Machine
pkg debug/elf, const EM_L10M = 180
pkg debug/elf, const EM_L10M Machine
pkg debug/elf, const EM_LANAI = 244
pkg debug/elf, const EM_LANAI Machine
pkg debug/elf, const EM_LATTICEMICO32 = 138
pkg debug/elf, const EM_LATTICEMICO32 Machine
pkg debug/elf, const EM_M16C = 117
pkg debug/elf, const EM_M16C Machine
pkg debug/elf, const EM_M32C = 120
pkg debug/elf, const EM_M32C Machine
pkg debug/elf, const EM_M32R = 88
pkg debug/elf, const EM_M32R Machine
pkg debug/elf, const EM_MANIK = 171
pkg debug/elf, const EM_MANIK Machine
pkg debug/elf, const EM_MAX = 102
pkg debug/elf, const EM_MAX Machine
pkg debug/elf, const EM_MAXQ30 = 169
pkg debug/elf, const EM_MAXQ30 Machine
pkg debug/elf, const EM_MCHP_PIC = 204
pkg debug/elf, const EM_MCHP_PIC Machine
pkg debug/elf, const EM_MCST_ELBRUS = 175
pkg debug/elf, const EM_MCST_ELBRUS Machine
pkg debug/elf, const EM_METAG = 174
pkg debug/elf, const EM_METAG Machine
pkg debug/elf, const EM_MICROBLAZE = 189
pkg debug/elf, const EM_MICROBLAZE Machine
pkg debug/elf, const EM_MMDSP_PLUS = 160
pkg debug/elf, const EM_MMDSP_PLUS Machine
pkg debug/elf, const EM_MMIX = 80
pkg debug/elf, const EM_MMIX Machine
pkg debug/elf, const EM_MN10200 = 90
pkg debug/elf, const EM_MN10200 Machine
pkg debug/elf, const EM_MN10300 = 89
pkg debug/elf, const EM_MN10300 Machine
pkg debug/elf, const EM_MOXIE = 223
pkg debug/elf, const EM_MOXIE Machine
pkg debug/elf, const EM_MSP430 = 105
pkg debug/elf, const EM_MSP430 Machine
pkg debug/elf, const EM_NDS32 = 167
pkg debug/elf, const EM_NDS32 Machine
pkg debug/elf, const EM_NORC = 218
pkg debug/elf, const EM_NORC Machine
pkg debug/elf, const EM_NS32K = 97
pkg debug/elf, const EM_NS32K Machine
pkg debug/elf, const EM_OPEN8 = 196
pkg debug/elf, const EM_OPEN8 Machine
pkg debug/elf, const EM_OPENRISC = 92
pkg debug/elf, const EM_OPENRISC Machine
pkg debug/elf, const EM_PDP10 = 64
pkg debug/elf, const EM_PDP10 Machine
pkg debug/elf, const EM_PDP11 = 65
pkg debug/elf, const EM_PDP11 Machine
pkg debug/elf, const EM_PDSP = 63
pkg debug/elf, const EM_PDSP Machine
pkg debug/elf, const EM_PJ = 91
pkg debug/elf, const EM_PJ Machine
pkg debug/elf, const EM_PRISM = 82
pkg debug/elf, const EM_PRISM Machine
pkg debug/elf, const EM_QDSP6 = 164
pkg debug/elf, const EM_QDSP6 Machine
pkg debug/elf, const EM_R32C = 162
pkg debug/elf, const EM_R32C Machine
pkg debug/elf, const EM_RISCV = 243
pkg debug/elf, const EM_RISCV Machine
pkg debug/elf, const EM_RL78 = 197
pkg debug/elf, const EM_RL78 Machine
pkg debug/elf, const EM_RS08 = 132
pkg debug/elf, const EM_RS08 Machine
pkg debug/elf, const EM_RX = 173
pkg debug/elf, const EM_RX Machine
pkg debug/elf, const EM_SCORE7 = 135
pkg debug/elf, const EM_SCORE7 Machine
pkg debug/elf, const EM_SEP = 108
pkg debug/elf, const EM_SEP Machine
pkg debug/elf, const EM_SE_C17 = 139
pkg debug/elf, const EM_SE_C17 Machine
pkg debug/elf, const EM_SE_C33 = 107
pkg debug/elf, const EM_SE_C33 Machine
pkg debug/elf, const EM_SHARC = 133
pkg debug/elf, const EM_SHARC Machine
pkg debug/elf, const EM_SLE9X = 179
pkg debug/elf, const EM_SLE9X Machine
pkg debug/elf, const EM_SNP1K = 99
pkg debug/elf, const EM_SNP1K Machine
pkg debug/elf, const EM_ST19 = 74
pkg debug/elf, const EM_ST19 Machine
pkg debug/elf, const EM_ST200 = 100
pkg debug/elf, const EM_ST200 Machine
pkg debug/elf, const EM_ST7 = 68
pkg debug/elf, const EM_ST7 Machine
pkg debug/elf, const EM_ST9PLUS = 67
pkg debug/elf, const EM_ST9PLUS Machine
pkg debug/elf, const EM_STM8 = 186
pkg debug/elf, const EM_STM8 Machine
pkg debug/elf, const EM_STXP7X = 166
pkg debug/elf, const EM_STXP7X Machine
pkg debug/elf, const EM_SVX = 73
pkg debug/elf, const EM_SVX Machine
pkg debug/elf, const EM_TILE64 = 187
pkg debug/elf, const EM_TILE64 Machine
pkg debug/elf, const EM_TILEGX = 191
pkg debug/elf, const EM_TILEGX Machine
pkg debug/elf, const EM_TILEPRO = 188
pkg debug/elf, const EM_TILEPRO Machine
pkg debug/elf, const EM_TI_ARP32 = 143
pkg debug/elf, const EM_TI_ARP32 Machine
pkg debug/elf, const EM_TI_C2000 = 141
pkg debug/elf, const EM_TI_C2000 Machine
pkg debug/elf, const EM_TI_C5500 = 142
pkg debug/elf, const EM_TI_C5500 Machine
pkg debug/elf, const EM_TI_C6000 = 140
pkg debug/elf, const EM_TI_C6000 Machine
pkg debug/elf, const EM_TI_PRU = 144
pkg debug/elf, const EM_TI_PRU Machine
pkg debug/elf, const EM_TMM_GPP = 96
pkg debug/elf, const EM_TMM_GPP Machine
pkg debug/elf, const EM_TPC = 98
pkg debug/elf, const EM_TPC Machine
pkg debug/elf, const EM_TRIMEDIA = 163
pkg debug/elf, const EM_TRIMEDIA Machine
pkg debug/elf, const EM_TSK3000 = 131
pkg debug/elf, const EM_TSK3000 Machine
pkg debug/elf, const EM_UNICORE = 110
pkg debug/elf, const EM_UNICORE Machine
pkg debug/elf, const EM_V850 = 87
pkg debug/elf, const EM_V850 Machine
pkg debug/elf, const EM_VAX = 75
pkg debug/elf, const EM_VAX Machine
pkg debug/elf, const EM_VIDEOCORE = 95
pkg debug/elf, const EM_VIDEOCORE Machine
pkg debug/elf, const EM_VIDEOCORE3 = 137
pkg debug/elf, const EM_VIDEOCORE3 Machine
pkg debug/elf, const EM_VIDEOCORE5 = 198
pkg debug/elf, const EM_VIDEOCORE5 Machine
pkg debug/elf, const EM_VISIUM = 221
pkg debug/elf, const EM_VISIUM Machine
pkg debug/elf, const EM_XCORE = 203
pkg debug/elf, const EM_XCORE Machine
pkg debug/elf, const EM_XGATE = 115
pkg debug/elf, const EM_XGATE Machine
pkg debug/elf, const EM_XIMO16 = 170
pkg debug/elf, const EM_XIMO16 Machine
pkg debug/elf, const EM_XTENSA = 94
pkg debug/elf, const EM_XTENSA Machine
pkg debug/elf, const EM_Z80 = 220
pkg debug/elf, const EM_Z80 Machine
pkg debug/elf, const EM_ZSP = 79
pkg debug/elf, const EM_ZSP Machine
pkg debug/elf, const R_RISCV_32 = 1
pkg debug/elf, const R_RISCV_32 R_RISCV
pkg debug/elf, const R_RISCV_64 = 2
pkg debug/elf, const R_RISCV_64 R_RISCV
pkg debug/elf, const R_RISCV_ADD16 = 34
pkg debug/elf, const R_RISCV_ADD16 R_RISCV
pkg debug/elf, const R_RISCV_ADD32 = 35
pkg debug/elf, const R_RISCV_ADD32 R_RISCV
pkg debug/elf, const R_RISCV_ADD64 = 36
pkg debug/elf, const R_RISCV_ADD64 R_RISCV
pkg debug/elf, const R_RISCV_ADD8 = 33
pkg debug/elf, const R_RISCV_ADD8 R_RISCV
pkg debug/elf, const R_RISCV_ALIGN = 43
pkg debug/elf, const R_RISCV_ALIGN R_RISCV
pkg debug/elf, const R_RISCV_BRANCH = 16
pkg debug/elf, const R_RISCV_BRANCH R_RISCV
pkg debug/elf, const R_RISCV_CALL = 18
pkg debug/elf, const R_RISCV_CALL R_RISCV
pkg debug/elf, const R_RISCV_CALL_PLT = 19
pkg debug/elf, const R_RISCV_CALL_PLT R_RISCV
pkg debug/elf, const R_RISCV_COPY = 4
pkg debug/elf, const R_RISCV_COPY R_RISCV
pkg debug/elf, const R_RISCV_GNU_VTENTRY = 42
pkg debug/elf, const R_RISCV_GNU_VTENTRY R_RISCV
pkg debug/elf, const R_RISCV_GNU_VTINHERIT = 41
pkg debug/elf, const R_RISCV_GNU_VTINHERIT R_RISCV
pkg debug/elf, const R_RISCV_GOT_HI20 = 20
pkg debug/elf, const R_RISCV_GOT_HI20 R_RISCV
pkg debug/elf, const R_RISCV_GPREL_I = 47
pkg debug/elf, const R_RISCV_GPREL_I R_RISCV
pkg debug/elf, const R_RISCV_GPREL_S = 48
pkg debug/elf, const R_RISCV_GPREL_S R_RISCV
pkg debug/elf, const R_RISCV_HI20 = 26
pkg debug/elf, const R_RISCV_HI20 R_RISCV
pkg debug/elf, const R_RISCV_JAL = 17
pkg debug/elf, const R_RISCV_JAL R_RISCV
pkg debug/elf, const R_RISCV_JUMP_SLOT = 5
pkg debug/elf, const R_RISCV_JUMP_SLOT R_RISCV
pkg debug/elf, const R_RISCV_LO12_I = 27
pkg debug/elf, const R_RISCV_LO12_I R_RISCV
pkg debug/elf, const R_RISCV_LO12_S = 28
pkg debug/elf, const R_RISCV_LO12_S R_RISCV
pkg debug/elf, const R_RISCV_NONE = 0
pkg debug/elf, const R_RISCV_NONE R_RISCV
pkg debug/elf, const R_RISCV_PCREL_HI20 = 23
pkg debug/elf, const R_RISCV_PCREL_HI20 R_RISCV
pkg debug/elf, const R_RISCV_PCREL_LO12_I = 24
pkg debug/elf, const R_RISCV_PCREL_LO12_I R_RISCV
pkg debug/elf, const R_RISCV_PCREL_LO12_S = 25
pkg debug/elf, const R_RISCV_PCREL_LO12_S R_RISCV
pkg debug/elf, const R_RISCV_RELATIVE = 3
pkg debug/elf, const R_RISCV_RELATIVE R_RISCV
pkg debug/elf, const R_RISCV_RELAX = 51
pkg debug/elf, const R_RISCV_RELAX R_RISCV
pkg debug/elf, const R_RISCV_RVC_BRANCH = 44
pkg debug/elf, const R_RISCV_RVC_BRANCH R_RISCV
pkg debug/elf, const R_RISCV_RVC_JUMP = 45
pkg debug/elf, const R_RISCV_RVC_JUMP R_RISCV
pkg debug/elf, const R_RISCV_RVC_LUI = 46
pkg debug/elf, const R_RISCV_RVC_LUI R_RISCV
pkg debug/elf, const R_RISCV_SET16 = 55
pkg debug/elf, const R_RISCV_SET16 R_RISCV
pkg debug/elf, const R_RISCV_SET32 = 56
pkg debug/elf, const R_RISCV_SET32 R_RISCV
pkg debug/elf, const R_RISCV_SET6 = 53
pkg debug/elf, const R_RISCV_SET6 R_RISCV
pkg debug/elf, const R_RISCV_SET8 = 54
pkg debug/elf, const R_RISCV_SET8 R_RISCV
pkg debug/elf, const R_RISCV_SUB16 = 38
pkg debug/elf, const R_RISCV_SUB16 R_RISCV
pkg debug/elf, const R_RISCV_SUB32 = 39
pkg debug/elf, const R_RISCV_SUB32 R_RISCV
pkg debug/elf, const R_RISCV_SUB6 = 52
pkg debug/elf, const R_RISCV_SUB6 R_RISCV
pkg debug/elf, const R_RISCV_SUB64 = 40
pkg debug/elf, const R_RISCV_SUB64 R_RISCV
pkg debug/elf, const R_RISCV_SUB8 = 37
pkg debug/elf, const R_RISCV_SUB8 R_RISCV
pkg debug/elf, const R_RISCV_TLS_DTPMOD32 = 6
pkg debug/elf, const R_RISCV_TLS_DTPMOD32 R_RISCV
pkg debug/elf, const R_RISCV_TLS_DTPMOD64 = 7
pkg debug/elf, const R_RISCV_TLS_DTPMOD64 R_RISCV
pkg debug/elf, const R_RISCV_TLS_DTPREL32 = 8
pkg debug/elf, const R_RISCV_TLS_DTPREL32 R_RISCV
pkg debug/elf, const R_RISCV_TLS_DTPREL64 = 9
pkg debug/elf, const R_RISCV_TLS_DTPREL64 R_RISCV
pkg debug/elf, const R_RISCV_TLS_GD_HI20 = 22
pkg debug/elf, const R_RISCV_TLS_GD_HI20 R_RISCV
pkg debug/elf, const R_RISCV_TLS_GOT_HI20 = 21
pkg debug/elf, const R_RISCV_TLS_GOT_HI20 R_RISCV
pkg debug/elf, const R_RISCV_TLS_TPREL32 = 10
pkg debug/elf, const R_RISCV_TLS_TPREL32 R_RISCV
pkg debug/elf, const R_RISCV_TLS_TPREL64 = 11
pkg debug/elf, const R_RISCV_TLS_TPREL64 R_RISCV
pkg debug/elf, const R_RISCV_TPREL_ADD = 32
pkg debug/elf, const R_RISCV_TPREL_ADD R_RISCV
pkg debug/elf, const R_RISCV_TPREL_HI20 = 29
pkg debug/elf, const R_RISCV_TPREL_HI20 R_RISCV
pkg debug/elf, const R_RISCV_TPREL_I = 49
pkg debug/elf, const R_RISCV_TPREL_I R_RISCV
pkg debug/elf, const R_RISCV_TPREL_LO12_I = 30
pkg debug/elf, const R_RISCV_TPREL_LO12_I R_RISCV
pkg debug/elf, const R_RISCV_TPREL_LO12_S = 31
pkg debug/elf, const R_RISCV_TPREL_LO12_S R_RISCV
pkg debug/elf, const R_RISCV_TPREL_S = 50
pkg debug/elf, const R_RISCV_TPREL_S R_RISCV
pkg debug/elf, method (R_RISCV) GoString() string
pkg debug/elf, method (R_RISCV) String() string
pkg debug/elf, type R_RISCV int
pkg debug/macho, const CpuArm64 = 16777228
pkg debug/macho, const CpuArm64 Cpu
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_ARCHITECTURE ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_BASERELOC = 5
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_BASERELOC ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_DEBUG = 6
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_DEBUG ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_EXCEPTION ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_EXPORT = 0
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_EXPORT ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_GLOBALPTR ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_IAT = 12
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_IAT ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_IMPORT = 1
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_IMPORT ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_RESOURCE = 2
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_RESOURCE ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_SECURITY = 4
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_SECURITY ideal-int
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_TLS = 9
pkg debug/pe, const IMAGE_DIRECTORY_ENTRY_TLS ideal-int
pkg debug/pe, const IMAGE_FILE_MACHINE_ARM64 = 43620
pkg debug/pe, const IMAGE_FILE_MACHINE_ARM64 ideal-int
pkg go/ast, type CompositeLit struct, Incomplete bool
pkg go/token, method (*File) AddLineColumnInfo(int, string, int, int)
pkg go/types, func NewInterfaceType([]*Func, []Type) *Interface
pkg go/types, method (*Interface) EmbeddedType(int) Type
pkg go/types, method (*Var) Embedded() bool
pkg net, method (*ListenConfig) Listen(context.Context, string, string) (Listener, error)
pkg net, method (*ListenConfig) ListenPacket(context.Context, string, string) (PacketConn, error)
pkg net, type Dialer struct, Control func(string, string, syscall.RawConn) error
pkg net, type ListenConfig struct
pkg net, type ListenConfig struct, Control func(string, string, syscall.RawConn) error
pkg net/http, const StatusMisdirectedRequest = 421
pkg net/http, const StatusMisdirectedRequest ideal-int
pkg net/http/httptrace, type ClientTrace struct, Got1xxResponse func(int, textproto.MIMEHeader) error
pkg os, const ModeIrregular = 524288
pkg os, const ModeIrregular FileMode
pkg os, const ModeType = 2399666176
pkg os, func UserCacheDir() (string, error)
pkg os/signal, func Ignored(os.Signal) bool
pkg regexp/syntax, method (Op) String() string
pkg runtime/trace, func IsEnabled() bool
pkg runtime/trace, func Log(context.Context, string, string)
pkg runtime/trace, func Logf(context.Context, string, string, ...interface{})
pkg runtime/trace, func NewTask(context.Context, string) (context.Context, *Task)
pkg runtime/trace, func StartRegion(context.Context, string) *Region
pkg runtime/trace, func WithRegion(context.Context, string, func())
pkg runtime/trace, method (*Region) End()
pkg runtime/trace, method (*Task) End()
pkg runtime/trace, type Region struct
pkg runtime/trace, type Task struct
pkg syscall (netbsd-386), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (netbsd-386), func Pipe2([]int, int) error
pkg syscall (netbsd-386-cgo), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (netbsd-386-cgo), func Pipe2([]int, int) error
pkg syscall (netbsd-amd64), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (netbsd-amd64), func Pipe2([]int, int) error
pkg syscall (netbsd-amd64-cgo), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (netbsd-amd64-cgo), func Pipe2([]int, int) error
pkg syscall (netbsd-arm), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (netbsd-arm), func Pipe2([]int, int) error
pkg syscall (netbsd-arm-cgo), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (netbsd-arm-cgo), func Pipe2([]int, int) error
pkg syscall (openbsd-386), const SOCK_CLOEXEC = 32768
pkg syscall (openbsd-386), const SOCK_CLOEXEC ideal-int
pkg syscall (openbsd-386), const SOCK_NONBLOCK = 16384
pkg syscall (openbsd-386), const SOCK_NONBLOCK ideal-int
pkg syscall (openbsd-386), const SYS_ACCEPT4 = 93
pkg syscall (openbsd-386), const SYS_ACCEPT4 ideal-int
pkg syscall (openbsd-386), const SYS_PIPE2 = 101
pkg syscall (openbsd-386), const SYS_PIPE2 ideal-int
pkg syscall (openbsd-386), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (openbsd-386), func Pipe2([]int, int) error
pkg syscall (openbsd-386-cgo), const SOCK_CLOEXEC = 32768
pkg syscall (openbsd-386-cgo), const SOCK_CLOEXEC ideal-int
pkg syscall (openbsd-386-cgo), const SOCK_NONBLOCK = 16384
pkg syscall (openbsd-386-cgo), const SOCK_NONBLOCK ideal-int
pkg syscall (openbsd-386-cgo), const SYS_ACCEPT4 = 93
pkg syscall (openbsd-386-cgo), const SYS_ACCEPT4 ideal-int
pkg syscall (openbsd-386-cgo), const SYS_PIPE2 = 101
pkg syscall (openbsd-386-cgo), const SYS_PIPE2 ideal-int
pkg syscall (openbsd-386-cgo), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (openbsd-386-cgo), func Pipe2([]int, int) error
pkg syscall (openbsd-amd64), const SOCK_CLOEXEC = 32768
pkg syscall (openbsd-amd64), const SOCK_CLOEXEC ideal-int
pkg syscall (openbsd-amd64), const SOCK_NONBLOCK = 16384
pkg syscall (openbsd-amd64), const SOCK_NONBLOCK ideal-int
pkg syscall (openbsd-amd64), const SYS_ACCEPT4 = 93
pkg syscall (openbsd-amd64), const SYS_ACCEPT4 ideal-int
pkg syscall (openbsd-amd64), const SYS_PIPE2 = 101
pkg syscall (openbsd-amd64), const SYS_PIPE2 ideal-int
pkg syscall (openbsd-amd64), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (openbsd-amd64), func Pipe2([]int, int) error
pkg syscall (openbsd-amd64-cgo), const SOCK_CLOEXEC = 32768
pkg syscall (openbsd-amd64-cgo), const SOCK_CLOEXEC ideal-int
pkg syscall (openbsd-amd64-cgo), const SOCK_NONBLOCK = 16384
pkg syscall (openbsd-amd64-cgo), const SOCK_NONBLOCK ideal-int
pkg syscall (openbsd-amd64-cgo), const SYS_ACCEPT4 = 93
pkg syscall (openbsd-amd64-cgo), const SYS_ACCEPT4 ideal-int
pkg syscall (openbsd-amd64-cgo), const SYS_PIPE2 = 101
pkg syscall (openbsd-amd64-cgo), const SYS_PIPE2 ideal-int
pkg syscall (openbsd-amd64-cgo), func Accept4(int, int) (int, Sockaddr, error)
pkg syscall (openbsd-amd64-cgo), func Pipe2([]int, int) error
pkg syscall (windows-386), const TOKEN_ADJUST_SESSIONID = 256
pkg syscall (windows-386), const TOKEN_ADJUST_SESSIONID ideal-int
pkg syscall (windows-386), const TOKEN_ALL_ACCESS = 983551
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara Pointer
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus Pointer
pkg syscall (windows-386), type CertContext struct, CertInfo *CertInfo
pkg syscall (windows-386), type CertInfo struct
pkg syscall (windows-386), type CertRevocationCrlInfo struct
pkg syscall (windows-386), type CertRevocationInfo struct, CrlInfo *CertRevocationCrlInfo
pkg syscall (windows-386), type CertRevocationInfo struct, OidSpecificInfo Pointer
pkg syscall (windows-386), type CertSimpleChain struct, TrustListInfo *CertTrustListInfo
pkg syscall (windows-386), type CertTrustListInfo struct
pkg syscall (windows-386), type Pointer *struct
pkg syscall (windows-amd64), const TOKEN_ADJUST_SESSIONID = 256
pkg syscall (windows-amd64), const TOKEN_ADJUST_SESSIONID ideal-int
pkg syscall (windows-amd64), const TOKEN_ALL_ACCESS = 983551
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara Pointer
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus Pointer
pkg syscall (windows-amd64), type CertContext struct, CertInfo *CertInfo
pkg syscall (windows-amd64), type CertInfo struct
pkg syscall (windows-amd64), type CertRevocationCrlInfo struct
pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo *CertRevocationCrlInfo
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo Pointer
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo *CertTrustListInfo
pkg syscall (windows-amd64), type CertTrustListInfo struct
pkg syscall (windows-amd64), type Pointer *struct
pkg syscall, const ImplementsGetwd = true
pkg text/template/parse, type PipeNode struct, IsAssign bool

View file

@ -110,6 +110,10 @@ packages and commands. Most Go programmers keep <i>all</i> their Go source code
and dependencies in a single workspace.
</p>
<p>
Note that symbolic links should <b>not</b> be used to link files or directories into your workspace.
</p>
<p>
Commands and libraries are built from different kinds of source packages.
We will discuss the distinction <a href="#PackageNames">later</a>.
@ -236,7 +240,7 @@ package main
import "fmt"
func main() {
fmt.Printf("Hello, world.\n")
fmt.Println("Hello, world.")
}
</pre>
@ -391,7 +395,7 @@ import (
)
func main() {
fmt.Printf(stringutil.Reverse("!oG ,olleH"))
fmt.Println(stringutil.Reverse("!oG ,olleH"))
}
</pre>
@ -669,7 +673,7 @@ articles about the Go language and its libraries and tools.
<p>
For real-time help, ask the helpful gophers in <code>#go-nuts</code> on the
<a href="http://freenode.net/">Freenode</a> IRC server.
<a href="https://freenode.net/">Freenode</a> IRC server.
</p>
<p>

View file

@ -92,10 +92,10 @@ account to use.
</p>
<p>
Google accounts can either be Gmail e-mail accounts, G-Suite organization accounts, or
Google accounts can either be Gmail e-mail accounts, G Suite organization accounts, or
accounts associated with an external e-mail address.
For instance, if you need to use
an existing corporate e-mail that is not managed through G-Suite, you can create
an existing corporate e-mail that is not managed through G Suite, you can create
an account associated
<a href="https://accounts.google.com/SignUpWithoutGmail">with your existing
e-mail address</a>.
@ -168,7 +168,7 @@ completed and update the <code>AUTHORS</code> file.
<h3 id="config_git_auth">Step 2: Configure git authentication</h3>
<p>
Go development happens on
The main Go repository is located at
<a href="https://go.googlesource.com">go.googlesource.com</a>,
a Git server hosted by Google.
Authentication on the web server is made through your Google account, but
@ -190,8 +190,8 @@ This key is paired with one that is generated and stored on the server,
analogous to how SSH keys work.
</li>
<li>
Copy and run this script locally in your command line terminal to store your
secret authentication token in a <code>.gitcookies</code> file.
Copy and run this script locally in your terminal to store your secret
authentication token in a <code>.gitcookies</code> file.
If you are using a Windows computer and running <code>cmd</code>,
you should instead follow the instructions in the yellow box to run the command;
otherwise run the regular script.
@ -251,12 +251,13 @@ symbolic link or just copy the executable from $GOPATH/bin to this directory.
<h2 id="before_contributing">Before contributing code</h2>
<p>
The project welcomes submissions but to make sure things are well
coordinated we ask that everyone to discuss any significant changes to the
Go repositories before starting work.
Best practice is to connect your work to the issue tracker,
either by <a href="https://golang.org/issue/new">filing a new issue</a>
or by claiming an <a href="https://golang.org/issues">existing issue</a>.
The project welcomes code patches, but to make sure things are well
coordinated you should discuss any significant change before starting
the work.
It's recommended that you signal your intention to contribute in the
issue tracker, either by <a href="https://golang.org/issue/new">filing
a new issue</a> or by claiming
an <a href="https://golang.org/issues">existing one</a>.
</p>
<h3>Check the issue tracker</h3>
@ -309,13 +310,13 @@ When planning work, please note that the Go project follows a <a
href="https://golang.org/wiki/Go-Release-Cycle">six-month development cycle</a>.
The latter half of each cycle is a three-month feature freeze during
which only bug fixes and documentation updates are accepted.
New contributions can be
sent during a feature freeze but will not be accepted until the freeze is over.
New contributions can be sent during a feature freeze, but they will
not be merged until the freeze is over.
</p>
<p>
Changes in general other than bug and documentation fixes
must go through the
Significant changes to the language, libraries, or tools must go
through the
<a href="https://golang.org/s/proposal-process">change proposal process</a>
before they can be accepted.
</p>
@ -337,10 +338,11 @@ GitHub pull requests to Gerrit.
<p>
Open a pull request as you normally would.
Gopherbot will automatically
sync the code and post a link to Gerrit.
When somebody comments on the
change, it will be posted in the pull request, so you will also get a notification.
Gopherbot will create a corresponding Gerrit change and post a link to
it on your GitHub pull request; updates to the pull request will also
get reflected in the Gerrit change.
When somebody comments on the change, their comment will be also
posted in your pull request, so you will get a notification.
</p>
<p>
@ -384,10 +386,10 @@ This is an overview of the overall process:
<ul>
<li>
<b>Step 1:</b> Clone the Go source code from GitHub or go.googlesource.com
<b>Step 1:</b> Clone the Go source code from go.googlesource.com
and make sure it's stable by compiling and testing it once:
<pre>
$ git clone https://github.com/golang/go # or https://go.googlesource.com/go
$ git clone https://go.googlesource.com/go
$ cd go/src
$ ./all.bash # compile and test
</pre>
@ -418,7 +420,7 @@ $ ./all.bash # recompile and test
<li>
<b>Step 4:</b> Send the changes for review to Gerrit using <code>git</code>
<code>codereview</code> <code>mail</code>(which doesn't use e-mail, despite the name).
<code>codereview</code> <code>mail</code> (which doesn't use e-mail, despite the name).
<pre>
$ git codereview mail # send changes to Gerrit
</pre>
@ -545,7 +547,7 @@ ALL TESTS PASSED
<p>
You can use <code>make.bash</code> instead of <code>all.bash</code>
to just build the compiler and standard packages without running the test suite.
to just build the compiler and the standard library without running the test suite.
Once the <code>go</code> tool is built, it will be installed as <code>bin/go</code>
under the directory in which you cloned the Go repository, and you can
run it directly from there.
@ -597,8 +599,9 @@ if you prefer.
</p>
<p>
If you need to revise your change after the review, edit the files in correct branch,
add them to the Git staging area, and then amend the commit with
If you need to revise your change after the review, edit the files in
the same branch you previously created, add them to the Git staging
area, and then amend the commit with
<code>git</code> <code>codereview</code> <code>change</code>:
</p>
@ -639,7 +642,7 @@ The existing implementation has poor numerical properties for
large arguments, so use the McGillicutty algorithm to improve
accuracy above 1e10.
The algorithm is described at http://wikipedia.org/wiki/McGillicutty_Algorithm
The algorithm is described at https://wikipedia.org/wiki/McGillicutty_Algorithm
Fixes #159
</pre>
@ -674,7 +677,7 @@ Don't use HTML, Markdown, or any other markup language.
<p>
Add any relevant information, such as benchmark data if the change
afects performance.
affects performance.
The <a href="https://godoc.org/golang.org/x/tools/cmd/benchcmp">benchcmp</a>
tool is conventionally used to format
benchmark data for change descriptions.
@ -937,7 +940,7 @@ remote: ERROR: does not match your user account.
<p>
you need to configure Git for this repository to use the
e-mail address that you registered with.
To change the e-mail address for this doesn't happen again, run:
To change the e-mail address to ensure this doesn't happen again, run:
</p>
<pre>
@ -984,8 +987,8 @@ followed by <code>run.bash</code>.
<li>
In this section, we'll call the directory into which you cloned the Go repository <code>$GODIR</code>.
The <code>go</code> tool built by <code>$GODIR/make.bash</code>will be installed
in <code>$GODIR/bin/go</code>and you
The <code>go</code> tool built by <code>$GODIR/make.bash</code> will be installed
in <code>$GODIR/bin/go</code> and you
can invoke it to test your code.
For instance, if you
have modified the compiler and you want to test how it affects the

View file

@ -47,7 +47,7 @@ In short, the instructions below should be taken only as a guide to how
to use GDB when it works, not as a guarantee of success.
Besides this overview you might want to consult the
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
<a href="https://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
</p>
<p>
@ -57,7 +57,7 @@ Besides this overview you might want to consult the
<p>
When you compile and link your Go programs with the <code>gc</code> toolchain
on Linux, Mac OS X, FreeBSD or NetBSD, the resulting binaries contain DWARFv4
on Linux, macOS, FreeBSD or NetBSD, the resulting binaries contain DWARFv4
debugging information that recent versions (&ge;7.5) of the GDB debugger can
use to inspect a live process or a core dump.
</p>

View file

@ -50,7 +50,7 @@ trace. Use tools in isolation to get more precise info.
Profiling is useful for identifying expensive or frequently called sections
of code. The Go runtime provides <a href="https://golang.org/pkg/runtime/pprof/">
profiling data</a> in the format expected by the
<a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>.
<a href="https://github.com/google/pprof/blob/master/doc/README.md">pprof visualization tool</a>.
The profiling data can be collected during testing
via <code>go</code> <code>test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter
@ -127,7 +127,7 @@ so it is recommended to collect only a single profile at a time.
<p>
The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a>
visualization of the profile data using
<code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>.
<code><a href="https://github.com/google/pprof/blob/master/doc/README.md">go tool pprof</a></code>.
Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a>
to see them in action.
</p>

View file

@ -195,7 +195,7 @@ See the <a href="/wiki/Articles">Articles page</a> at the
<img class="gopher" src="/doc/gopher/talks.png"/>
<h3 id="video_tour_of_go"><a href="http://research.swtch.com/gotour">A Video Tour of Go</a></h3>
<h3 id="video_tour_of_go"><a href="https://research.swtch.com/gotour">A Video Tour of Go</a></h3>
<p>
Three things that make Go fast, fun, and productive:
interfaces, reflection, and concurrency. Builds a toy web crawler to

View file

@ -9,7 +9,7 @@
This document lists commonly used editor plugins and IDEs from the Go ecosystem
that make Go development more productive and seamless.
A comprehensive list of editor support and IDEs for Go development is available at
<a href="http://golang.org/wiki/IDEsAndTextEditorPlugins">the wiki</a>.
<a href="https://golang.org/wiki/IDEsAndTextEditorPlugins">the wiki</a>.
</p>
<h2 id="options">Options</h2>

View file

@ -22,7 +22,7 @@ file HACKING</a> in the gofrontend repository.
You must follow the <a href="/doc/contribute.html#copyright">Go copyright
rules</a> for all changes to the gccgo frontend and the associated
libgo library. Code that is part of GCC rather than gccgo must follow
the general <a href="http://gcc.gnu.org/contribute.html">GCC
the general <a href="https://gcc.gnu.org/contribute.html">GCC
contribution rules</a>.
</p>
@ -30,9 +30,9 @@ contribution rules</a>.
<p>
The master sources for the gccgo frontend may be found at
<a href="http://go.googlesource.com/gofrontend">http://go.googlesource.com/gofrontend</a>.
<a href="https://go.googlesource.com/gofrontend">https://go.googlesource.com/gofrontend</a>.
They are mirrored
at <a href="http://github.com/golang/gofrontend">http://github.com/golang/gofrontend</a>.
at <a href="https://github.com/golang/gofrontend">https://github.com/golang/gofrontend</a>.
The master sources are not buildable by themselves, but only in
conjunction with GCC (in the future, other compilers may be
supported). Changes made to the gccgo frontend are also applied to

View file

@ -9,7 +9,7 @@ the Go language. The gccgo compiler is a new frontend
for GCC, the widely used GNU compiler. Although the
frontend itself is under a BSD-style license, gccgo is
normally used as part of GCC and is then covered by
the <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public
the <a href="https://www.gnu.org/licenses/gpl.html">GNU General Public
License</a> (the license covers gccgo itself as part of GCC; it
does not cover code generated by gccgo).
</p>
@ -25,7 +25,7 @@ compiler.
<p>
The simplest way to install gccgo is to install a GCC binary release
built to include Go support. GCC binary releases are available from
<a href="http://gcc.gnu.org/install/binaries.html">various
<a href="https://gcc.gnu.org/install/binaries.html">various
websites</a> and are typically included as part of GNU/Linux
distributions. We expect that most people who build these binaries
will include Go support.
@ -79,7 +79,7 @@ If you cannot use a release, or prefer to build gccgo for
yourself,
the gccgo source code is accessible via Subversion. The
GCC web site
has <a href="http://gcc.gnu.org/svn.html">instructions for getting the
has <a href="https://gcc.gnu.org/svn.html">instructions for getting the
GCC source code</a>. The gccgo source code is included. As a
convenience, a stable version of the Go support is available in
a branch of the main GCC code
@ -101,7 +101,7 @@ gccgo</a>.
<p>
Building gccgo is just like building GCC
with one or two additional options. See
the <a href="http://gcc.gnu.org/install/">instructions on the gcc web
the <a href="https://gcc.gnu.org/install/">instructions on the gcc web
site</a>. When you run <code>configure</code>, add the
option <code>--enable-languages=c,c++,go</code> (along with other
languages you may want to build). If you are targeting a 32-bit x86,
@ -156,7 +156,7 @@ option <code>--with-ld=<var>GOLD_BINARY</var></code>.
<p>
A number of prerequisites are required to build GCC, as
described on
the <a href="http://gcc.gnu.org/install/prerequisites.html">gcc web
the <a href="https://gcc.gnu.org/install/prerequisites.html">gcc web
site</a>. It is important to install all the prerequisites before
running the gcc <code>configure</code> script.
The prerequisite libraries can be conveniently downloaded using the

346
doc/go1.11.html Normal file
View file

@ -0,0 +1,346 @@
<!--{
"Title": "Go 1.11 Release Notes",
"Path": "/doc/go1.11",
"Template": true
}-->
<!--
NOTE: In this document and others in this directory, the convention is to
set fixed-width phrases with non-fixed-width spaces, as in
<code>hello</code> <code>world</code>.
Do not send CLs removing the interior tags from such phrases.
-->
<style>
ul li { margin: 0.5em 0; }
</style>
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.11</h2>
<p>
<strong>
Go 1.11 is not yet released. These are work-in-progress
release notes. Go 1.11 is expected to be released in August 2018.
</strong>
</p>
<p>
The latest Go release, version 1.11, arrives six months after <a href="go1.10">Go 1.10</a>.
Most of its changes are in the implementation of the toolchain, runtime, and libraries.
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
We expect almost all Go programs to continue to compile and run as before.
</p>
<h2 id="language">Changes to the language</h2>
<p>
There are no changes to the language specification.
</p>
<h2 id="ports">Ports</h2>
<p>
As <a href="go1.10#ports">announced in the Go 1.10 release notes</a>, Go 1.11 now requires
OpenBSD 6.2 or later, macOS 10.10 Yosemite or later, or Windows 7 or later;
Support for previous versions of these operating systems has been removed.
</p>
<p>
There are <a href="https://golang.org/issue/25206">known issues</a> with NetBSD on i386 hardware.
</p>
<p><!-- CL 107935 -->
TODO: PPC64LE race detector support
</p>
<h3 id="package-versioning">Package Versioning (vgo)</h3>
<p>
<strong>
NOTE: This is not present in go1.11beta1 but will be available in future
betas and subsequent releases.
</strong>
Go 1.11 adds experimental, integrated support for package versioning.
</p>
<h3 id="wasm">WebAssembly</h3>
<p>
Go 1.11 adds an experimental port to WebAssembly (<code>js/wasm</code>).
</p>
<h2 id="library">Core library</h2>
<p>
All of the changes to the standard library are minor.
</p>
<h3 id="minor_library_changes">Minor changes to the library</h3>
<p>
As always, there are various minor changes and updates to the library,
made with the Go 1 <a href="/doc/go1compat">promise of compatibility</a>
in mind.
</p>
<!-- CL 113315: https://golang.org/cl/113315: cmd/asm: enable AVX512 -->
<!-- CL 100459: https://golang.org/cl/100459: cmd/compile: reject type switch with guarded declaration and no cases -->
<!-- CL 106797: https://golang.org/cl/106797: cmd/compile: enable indexed export format by default -->
<!-- CL 108475: https://golang.org/cl/108475: cmd/compile: add softfloat support to mips64{,le} -->
<!-- CL 97375: https://golang.org/cl/97375: cmd/compile, cmd/compile/internal/syntax: print relative column info -->
<!-- CL 110395: https://golang.org/cl/110395: cmd/go, cmd/compile: use Windows response files to avoid arg length limits -->
<!-- CL 107475: https://golang.org/cl/107475: cmd/internal/obj/arm, runtime: delete old ARM softfloat code -->
<!-- CL 112436: https://golang.org/cl/112436: cmd/pprof: add readline support similar to upstream -->
<dl id="all"><dt><a href="/pkg/all/">all</a></dt>
<dd>
<p><!-- CL 93875 -->
TODO: <a href="https://golang.org/cl/93875">https://golang.org/cl/93875</a>: enable c-shared/c-archive support for freebsd/amd64
</p>
<p><!-- CL 94255 -->
TODO: <a href="https://golang.org/cl/94255">https://golang.org/cl/94255</a>: drop support for Windows Vista or below (Windows XP)
</p>
<p><!-- CL 115038 -->
TODO: <a href="https://golang.org/cl/115038">https://golang.org/cl/115038</a>: remove support for macOS 10.9 and earlier
</p>
</dl><!-- all -->
<dl id="crypto"><dt><a href="/pkg/crypto/">crypto</a></dt>
<dd>
<p><!-- CL 64451 -->
TODO: <a href="https://golang.org/cl/64451">https://golang.org/cl/64451</a>: randomly read an extra byte of randomness in some places.
</p>
</dl><!-- crypto -->
<dl id="crypto/cipher"><dt><a href="/pkg/crypto/cipher/">crypto/cipher</a></dt>
<dd>
<p><!-- CL 48510, CL 116435 -->
TODO: <a href="https://golang.org/cl/48510">https://golang.org/cl/48510</a>: add NewGCMWithTagSize for custom tag sizes.
</p>
</dl><!-- crypto/cipher -->
<dl id="crypto/rsa"><dt><a href="/pkg/crypto/rsa/">crypto/rsa</a></dt>
<dd>
<p><!-- CL 103876 -->
TODO: <a href="https://golang.org/cl/103876">https://golang.org/cl/103876</a>: add PublicKey.Size accessor
</p>
</dl><!-- crypto/rsa -->
<dl id="debug/elf"><dt><a href="/pkg/debug/elf/">debug/elf</a></dt>
<dd>
<p><!-- CL 112115 -->
TODO: <a href="https://golang.org/cl/112115">https://golang.org/cl/112115</a>: add machine and OSABI constants
</p>
</dl><!-- debug/elf -->
<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1/">encoding/asn1</a></dt>
<dd>
<p><!-- CL 110561 -->
TODO: <a href="https://golang.org/cl/110561">https://golang.org/cl/110561</a>: allow Marshaling and Unmarshaling private tag class
</p>
</dl><!-- encoding/asn1 -->
<dl id="encoding/base32"><dt><a href="/pkg/encoding/base32/">encoding/base32</a></dt>
<dd>
<p><!-- CL 112516 -->
TODO: <a href="https://golang.org/cl/112516">https://golang.org/cl/112516</a>: handle surplus padding consistently
</p>
</dl><!-- encoding/base32 -->
<dl id="encoding/csv"><dt><a href="/pkg/encoding/csv/">encoding/csv</a></dt>
<dd>
<p><!-- CL 99696 -->
TODO: <a href="https://golang.org/cl/99696">https://golang.org/cl/99696</a>: disallow quote for use as Comma
</p>
</dl><!-- encoding/csv -->
<dl id="go/build, runtime/internal/sys"><dt><a href="/pkg/go/build, runtime/internal/sys/">go/build, runtime/internal/sys</a></dt>
<dd>
<p><!-- CL 106256 -->
TODO: <a href="https://golang.org/cl/106256">https://golang.org/cl/106256</a>: reserve RISC-V arch names
</p>
</dl><!-- go/build, runtime/internal/sys -->
<dl id="image/gif"><dt><a href="/pkg/image/gif/">image/gif</a></dt>
<dd>
<p><!-- CL 93076 -->
TODO: <a href="https://golang.org/cl/93076">https://golang.org/cl/93076</a>: support non-looping animated gifs (LoopCount=-1)
</p>
</dl><!-- image/gif -->
<dl id="io/ioutil"><dt><a href="/pkg/io/ioutil/">io/ioutil</a></dt>
<dd>
<p><!-- CL 105675 -->
TODO: <a href="https://golang.org/cl/105675">https://golang.org/cl/105675</a>: change TempFile prefix to a pattern
</p>
</dl><!-- io/ioutil -->
<dl id="math/big"><dt><a href="/pkg/math/big/">math/big</a></dt>
<dd>
<p><!-- CL 74851 -->
TODO: <a href="https://golang.org/cl/74851">https://golang.org/cl/74851</a>: speed-up addMulVVW on amd64
</p>
</dl><!-- math/big -->
<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
<dd>
<p><!-- CL 72810 -->
TODO: <a href="https://golang.org/cl/72810">https://golang.org/cl/72810</a>: add ListenConfig, Dialer.Control to permit socket opts before listen/dial
</p>
<p><!-- CL 76391 -->
TODO: <a href="https://golang.org/cl/76391">https://golang.org/cl/76391</a>: implement (*syscall.RawConn).Read/Write on Windows
</p>
<p><!-- CL 107715 -->
TODO: <a href="https://golang.org/cl/107715">https://golang.org/cl/107715</a>: add support for splice(2) in (*TCPConn).ReadFrom on Linux
</p>
<p><!-- CL 108297 -->
TODO: <a href="https://golang.org/cl/108297">https://golang.org/cl/108297</a>: calling File leaves the socket in nonblocking mode
</p>
</dl><!-- net -->
<dl id="net/http"><dt><a href="/pkg/net/http/">net/http</a></dt>
<dd>
<p><!-- CL 89275 -->
TODO: <a href="https://golang.org/cl/89275">https://golang.org/cl/89275</a>: don&#39;t sniff Content-type in Server when X-Content-Type-Options:nosniff
</p>
<p><!-- CL 93296 -->
TODO: <a href="https://golang.org/cl/93296">https://golang.org/cl/93296</a>: add StatusMisdirectedRequest (421)
</p>
</dl><!-- net/http -->
<dl id="os"><dt><a href="/pkg/os/">os</a></dt>
<dd>
<p><!-- CL 78835 -->
TODO: <a href="https://golang.org/cl/78835">https://golang.org/cl/78835</a>: add UserCacheDir
</p>
<p><!-- CL 94856 -->
TODO: <a href="https://golang.org/cl/94856">https://golang.org/cl/94856</a>: add ModeIrregular flag
</p>
<p><!-- CL 99337 -->
TODO: <a href="https://golang.org/cl/99337">https://golang.org/cl/99337</a>: enable symlink creation on Windows 10
</p>
<p><!-- CL 100077 -->
TODO: <a href="https://golang.org/cl/100077">https://golang.org/cl/100077</a>: use poller when NewFile is called with a blocking descriptor.
</p>
</dl><!-- os -->
<dl id="os/signal"><dt><a href="/pkg/os/signal/">os/signal</a></dt>
<dd>
<p><!-- CL 108376 -->
TODO: <a href="https://golang.org/cl/108376">https://golang.org/cl/108376</a>: add func Ignored(sig Signal) bool
</p>
</dl><!-- os/signal -->
<dl id="os/user"><dt><a href="/pkg/os/user/">os/user</a></dt>
<dd>
<p><!-- CL 92456 -->
TODO: <a href="https://golang.org/cl/92456">https://golang.org/cl/92456</a>: add a way to enforce pure Go implementation
</p>
</dl><!-- os/user -->
<dl id="runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
<dd>
<p><!-- CL 85887 -->
TODO: <a href="https://golang.org/cl/85887">https://golang.org/cl/85887</a>: use sparse mappings for the heap
</p>
<p><!-- CL 94076 -->
TODO: <a href="https://golang.org/cl/94076">https://golang.org/cl/94076</a>: use native CAS and memory barrier on ARMv7
</p>
<p><!-- CL 106156 -->
TODO: <a href="https://golang.org/cl/106156">https://golang.org/cl/106156</a>: use fixed TLS offsets on darwin/amd64 and darwin/386
</p>
<p><!-- CL 109255 -->
TODO: <a href="https://golang.org/cl/109255">https://golang.org/cl/109255</a>: enable memory sanitizer on arm64
</p>
</dl><!-- runtime -->
<dl id="runtime,cmd/ld"><dt><a href="/pkg/runtime,cmd/ld/">runtime,cmd/ld</a></dt>
<dd>
<p><!-- CL 108679 -->
TODO: <a href="https://golang.org/cl/108679">https://golang.org/cl/108679</a>: on darwin, create theads using libc
</p>
</dl><!-- runtime,cmd/ld -->
<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
<dd>
<p><!-- CL 102696 -->
TODO: <a href="https://golang.org/cl/102696">https://golang.org/cl/102696</a>: introduce &#34;allocs&#34; profile
</p>
</dl><!-- runtime/pprof -->
<dl id="runtime/traceback"><dt><a href="/pkg/runtime/traceback/">runtime/traceback</a></dt>
<dd>
<p><!-- CL 70993 -->
TODO: <a href="https://golang.org/cl/70993">https://golang.org/cl/70993</a>: support tracking goroutine ancestor tracebacks with GODEBUG=&#34;tracebackancestors=N&#34;
</p>
</dl><!-- runtime/traceback -->
<dl id="sync"><dt><a href="/pkg/sync/">sync</a></dt>
<dd>
<p><!-- CL 87095 -->
TODO: <a href="https://golang.org/cl/87095">https://golang.org/cl/87095</a>: enable profiling of RWMutex
</p>
</dl><!-- sync -->
<dl id="syscall"><dt><a href="/pkg/syscall/">syscall</a></dt>
<dd>
<p><!-- CL 106275 -->
TODO: <a href="https://golang.org/cl/106275">https://golang.org/cl/106275</a>: introduce Pointer type and use it instead of uintptr
</p>
</dl><!-- syscall -->
<dl id="text/scanner"><dt><a href="/pkg/text/scanner/">text/scanner</a></dt>
<dd>
<p><!-- CL 112037 -->
TODO: <a href="https://golang.org/cl/112037">https://golang.org/cl/112037</a>: return RawString token rather than String for raw string literals
</p>
</dl><!-- text/scanner -->
<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
<dd>
<p><!-- CL 84480 -->
TODO: <a href="https://golang.org/cl/84480">https://golang.org/cl/84480</a>: add variable assignments
</p>
</dl><!-- text/template -->
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
<dd>
<p><!-- CL 98157 -->
TODO: <a href="https://golang.org/cl/98157">https://golang.org/cl/98157</a>: add support for parsing timezones denoted by sign and offset
</p>
</dl><!-- time -->

View file

@ -860,13 +860,13 @@ The new build tag <code>netgo</code> (off by default) allows the construction of
The <a href="/pkg/net/"><code>net</code></a> package adds a new field
<code>DualStack</code> to the <a href="/pkg/net/#Dialer"><code>Dialer</code></a>
struct for TCP connection setup using a dual IP stack as described in
<a href="http://tools.ietf.org/html/rfc6555">RFC 6555</a>.
<a href="https://tools.ietf.org/html/rfc6555">RFC 6555</a>.
</li>
<li>
The <a href="/pkg/net/http/"><code>net/http</code></a> package will no longer
transmit cookies that are incorrect according to
<a href="http://tools.ietf.org/html/rfc6265">RFC 6265</a>.
<a href="https://tools.ietf.org/html/rfc6265">RFC 6265</a>.
It just logs an error and sends nothing.
Also,
the <a href="/pkg/net/http/"><code>net/http</code></a> package's

View file

@ -420,7 +420,7 @@ to automate the running of tools to generate source code before compilation.
For example, it can be used to run the <a href="/cmd/yacc"><code>yacc</code></a>
compiler-compiler on a <code>.y</code> file to produce the Go source file implementing the grammar,
or to automate the generation of <code>String</code> methods for typed constants using the new
<a href="http://godoc.org/golang.org/x/tools/cmd/stringer">stringer</a>
<a href="https://godoc.org/golang.org/x/tools/cmd/stringer">stringer</a>
tool in the <code>golang.org/x/tools</code> subrepository.
</p>
@ -619,9 +619,9 @@ has been created to serve as the location for new developments to support system
calls on all kernels.
It has a nicer structure, with three packages that each hold the implementation of
system calls for one of
<a href="http://godoc.org/golang.org/x/sys/unix">Unix</a>,
<a href="http://godoc.org/golang.org/x/sys/windows">Windows</a> and
<a href="http://godoc.org/golang.org/x/sys/plan9">Plan 9</a>.
<a href="https://godoc.org/golang.org/x/sys/unix">Unix</a>,
<a href="https://godoc.org/golang.org/x/sys/windows">Windows</a> and
<a href="https://godoc.org/golang.org/x/sys/plan9">Plan 9</a>.
These packages will be curated more generously, accepting all reasonable changes
that reflect kernel interfaces in those operating systems.
See the documentation and the article mentioned above for more information.
@ -670,7 +670,7 @@ The <a href="/pkg/crypto/"><code>crypto</code></a> package now has a
<li>
The <a href="/pkg/crypto/tls/"><code>crypto/tls</code></a> package
now supports ALPN as defined in <a href="http://tools.ietf.org/html/rfc7301">RFC 7301</a>.
now supports ALPN as defined in <a href="https://tools.ietf.org/html/rfc7301">RFC 7301</a>.
</li>
<li>

View file

@ -116,7 +116,7 @@ instead of generated from <a href="/cmd/yacc/">yacc</a>.
<p>
The compiler, linker, and <code>go</code> command have a new flag <code>-msan</code>,
analogous to <code>-race</code> and only available on linux/amd64,
that enables interoperation with the <a href="http://clang.llvm.org/docs/MemorySanitizer.html">Clang MemorySanitizer</a>.
that enables interoperation with the <a href="https://clang.llvm.org/docs/MemorySanitizer.html">Clang MemorySanitizer</a>.
Such interoperation is useful mainly for testing a program containing suspect C or C++ code.
</p>

View file

@ -89,7 +89,7 @@ POWER5 architecture.
</p>
<p>
The OpenBSD port now requires OpenBSD 5.6 or later, for access to the <a href="http://man.openbsd.org/getentropy.2"><i>getentropy</i>(2)</a> system call.
The OpenBSD port now requires OpenBSD 5.6 or later, for access to the <a href="https://man.openbsd.org/getentropy.2"><i>getentropy</i>(2)</a> system call.
</p>
<h3 id="known_issues">Known Issues</h3>

View file

@ -97,14 +97,14 @@ What's the origin of the mascot?</h3>
<p>
The mascot and logo were designed by
<a href="http://reneefrench.blogspot.com">Renée French</a>, who also designed
<a href="https://reneefrench.blogspot.com">Renée French</a>, who also designed
<a href="https://9p.io/plan9/glenda.html">Glenda</a>,
the Plan 9 bunny.
The <a href="https://blog.golang.org/gopher">gopher</a>
is derived from one she used for an <a href="http://wfmu.org/">WFMU</a>
is derived from one she used for an <a href="https://wfmu.org/">WFMU</a>
T-shirt design some years ago.
The logo and mascot are covered by the
<a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a>
<a href="https://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a>
license.
</p>
@ -1396,7 +1396,7 @@ reservation does not deprive other processes of memory.
<p>
To find the amount of actual memory allocated to a Go process, use the Unix
<code>top</code> command and consult the <code>RES</code> (Linux) or
<code>RSIZE</code> (Mac OS X) columns.
<code>RSIZE</code> (macOS) columns.
<!-- TODO(adg): find out how this works on Windows -->
</p>
@ -1929,7 +1929,7 @@ func main() {
<p>
Nowadays, most Go programmers use a tool,
<a href="http://godoc.org/golang.org/x/tools/cmd/goimports">goimports</a>,
<a href="https://godoc.org/golang.org/x/tools/cmd/goimports">goimports</a>,
which automatically rewrites a Go source file to have the correct imports,
eliminating the unused imports issue in practice.
This program is easily connected to most editors to run automatically when a Go source file is written.
@ -1968,7 +1968,7 @@ The slowest depend on libraries for which versions of comparable performance
are not available in Go.
For instance, <a href="https://go.googlesource.com/exp/+/master/shootout/pidigits.go">pidigits.go</a>
depends on a multi-precision math package, and the C
versions, unlike Go's, use <a href="http://gmplib.org/">GMP</a> (which is
versions, unlike Go's, use <a href="https://gmplib.org/">GMP</a> (which is
written in optimized assembler).
Benchmarks that depend on regular expressions
(<a href="https://go.googlesource.com/exp/+/master/shootout/regex-dna.go">regex-dna.go</a>,

View file

@ -69,7 +69,7 @@ language.
<p>
Source code is Unicode text encoded in
<a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a>. The text is not
<a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a>. The text is not
canonicalized, so a single accented code point is distinct from the
same character constructed from combining an accent and a letter;
those are treated as two code points. For simplicity, this document
@ -104,7 +104,7 @@ unicode_digit = /* a Unicode code point classified as "Number, decimal digit" *
</pre>
<p>
In <a href="http://www.unicode.org/versions/Unicode8.0.0/">The Unicode Standard 8.0</a>,
In <a href="https://www.unicode.org/versions/Unicode8.0.0/">The Unicode Standard 8.0</a>,
Section 4.5 "General Category" defines a set of character categories.
Go treats all characters in any of the Letter categories Lu, Ll, Lt, Lm, or Lo
as Unicode letters, and those in the Number category Nd as Unicode digits.
@ -793,7 +793,7 @@ rune alias for int32
<p>
The value of an <i>n</i>-bit integer is <i>n</i> bits wide and represented using
<a href="http://en.wikipedia.org/wiki/Two's_complement">two's complement arithmetic</a>.
<a href="https://en.wikipedia.org/wiki/Two's_complement">two's complement arithmetic</a>.
</p>
<p>
@ -3543,7 +3543,7 @@ x = q*y + r and |r| &lt; |y|
<p>
with <code>x / y</code> truncated towards zero
(<a href="http://en.wikipedia.org/wiki/Modulo_operation">"truncated division"</a>).
(<a href="https://en.wikipedia.org/wiki/Modulo_operation">"truncated division"</a>).
</p>
<pre>
@ -6109,7 +6109,7 @@ package and may be relative to a repository of installed packages.
<p>
Implementation restriction: A compiler may restrict ImportPaths to
non-empty strings using only characters belonging to
<a href="http://www.unicode.org/versions/Unicode6.3.0/">Unicode's</a>
<a href="https://www.unicode.org/versions/Unicode6.3.0/">Unicode's</a>
L, M, N, P, and S general categories (the Graphic characters without
spaces) and may also exclude the characters
<code>!"#$%&amp;'()*,:;&lt;=&gt;?[\]^`{|}</code>

View file

@ -98,7 +98,7 @@ goroutines, such as stacks that grow and shrink on demand.
<p>
The compilers can target the DragonFly BSD, FreeBSD, Linux, NetBSD, OpenBSD,
OS X (Darwin), Plan 9, Solaris and Windows operating systems.
macOS (Darwin), Plan 9, Solaris and Windows operating systems.
The full set of supported combinations is listed in the discussion of
<a href="#environment">environment variables</a> below.
</p>
@ -197,7 +197,7 @@ have a <code>git</code> command before proceeding.)
<p>
If you do not have a working Git installation,
follow the instructions on the
<a href="http://git-scm.com/downloads">Git downloads</a> page.
<a href="https://git-scm.com/downloads">Git downloads</a> page.
</p>
<h2 id="ccompiler">(Optional) Install a C compiler</h2>
@ -388,7 +388,7 @@ You can access the latter commands with
<p>
The usual community resources such as
<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server
<code>#go-nuts</code> on the <a href="https://freenode.net/">Freenode</a> IRC server
and the
<a href="//groups.google.com/group/golang-nuts">Go Nuts</a>
mailing list have active developers that can help you with problems
@ -468,7 +468,7 @@ These default to the values of <code>$GOHOSTOS</code> and
<p>
Choices for <code>$GOOS</code> are
<code>darwin</code> (Mac OS X 10.8 and above and iOS), <code>dragonfly</code>, <code>freebsd</code>,
<code>darwin</code> (macOS 10.10 and above and iOS), <code>dragonfly</code>, <code>freebsd</code>,
<code>linux</code>, <code>netbsd</code>, <code>openbsd</code>,
<code>plan9</code>, <code>solaris</code> and <code>windows</code>.
Choices for <code>$GOARCH</code> are

View file

@ -17,7 +17,7 @@
<p>
<a href="/dl/" target="_blank">Official binary
distributions</a> are available for the FreeBSD (release 10-STABLE and above),
Linux, Mac OS X (10.8 and above), and Windows operating systems and
Linux, macOS (10.10 and above), and Windows operating systems and
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
architectures.
</p>
@ -49,7 +49,7 @@ If your OS or architecture is not on the list, you may be able to
<tr><td colspan="3"><hr></td></tr>
<tr><td>FreeBSD 10.3 or later</td> <td>amd64, 386</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
<tr valign='top'><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm, arm64,<br>s390x, ppc64le</td> <td>CentOS/RHEL 5.x not supported.<br>Install from source for other libc.</td></tr>
<tr><td>macOS 10.8 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup> for <code>cgo</code> support</td></tr>
<tr><td>macOS 10.10 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>&#8224;</sup> that comes with Xcode<sup>&#8225;</sup> for <code>cgo</code> support</td></tr>
<tr><td>Windows XP SP2 or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>&#8224;</sup>. No need for cygwin or msys.</td></tr>
</table>
@ -57,7 +57,7 @@ If your OS or architecture is not on the list, you may be able to
<sup>&#8224;</sup>A C compiler is required only if you plan to use
<a href="/cmd/cgo">cgo</a>.<br/>
<sup>&#8225;</sup>You only need to install the command line tools for
<a href="http://developer.apple.com/Xcode/">Xcode</a>. If you have already
<a href="https://developer.apple.com/Xcode/">Xcode</a>. If you have already
installed Xcode 4.3+, you can install it from the Components tab of the
Downloads preferences panel.
</p>
@ -74,7 +74,7 @@ first <a href="#uninstall">remove the existing version</a>.
<div id="tarballInstructions">
<h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
<h3 id="tarball">Linux, macOS, and FreeBSD tarballs</h3>
<p>
<a href="/dl/">Download the archive</a>
@ -114,36 +114,11 @@ or execute them from the profile using a command such as
<code>source $HOME/.profile</code>.
</p>
<h4 id="tarball_non_standard">Installing to a custom location</h4>
<p>
The Go binary distributions assume they will be installed in
<code>/usr/local/go</code> (or <code>c:\Go</code> under Windows),
but it is possible to install the Go tools to a different location.
In this case you must set the <code>GOROOT</code> environment variable
to point to the directory in which it was installed.
</p>
<p>
For example, if you installed Go to your home directory you should add
commands like the following to <code>$HOME/.profile</code>:
</p>
<pre>
export GOROOT=$HOME/go1.X
export PATH=$PATH:$GOROOT/bin
</pre>
<p>
<b>Note</b>: <code>GOROOT</code> must be set only when installing to a custom
location.
</p>
</div><!-- tarballInstructions -->
<div id="darwinPackageInstructions">
<h3 id="osx">Mac OS X package installer</h3>
<h3 id="macos"><div id="osx"></div>macOS package installer</h3>
<p>
<a href="/dl/">Download the package file</a>,
@ -301,7 +276,7 @@ which describes some essential concepts about using the Go tools.
<p>
To remove an existing Go installation from your system delete the
<code>go</code> directory. This is usually <code>/usr/local/go</code>
under Linux, Mac OS X, and FreeBSD or <code>c:\Go</code>
under Linux, macOS, and FreeBSD or <code>c:\Go</code>
under Windows.
</p>
@ -310,7 +285,7 @@ You should also remove the Go <code>bin</code> directory from your
<code>PATH</code> environment variable.
Under Linux and FreeBSD you should edit <code>/etc/profile</code> or
<code>$HOME/.profile</code>.
If you installed Go with the <a href="#osx">Mac OS X package</a> then you
If you installed Go with the <a href="#macos">macOS package</a> then you
should remove the <code>/etc/paths.d/go</code> file.
Windows users should read the section about <a href="#windows_env">setting
environment variables under Windows</a>.

View file

@ -62,7 +62,7 @@ simple, reliable, and efficient software.
<span class="big">Download Go</span>
<span class="desc">
Binary distributions available for<br>
Linux, Mac OS X, Windows, and more.
Linux, macOS, Windows, and more.
</span>
</a>

View file

@ -8,8 +8,8 @@
# Consult https://www.iana.org/time-zones for the latest versions.
# Versions to use.
CODE=2017c
DATA=2017c
CODE=2018e
DATA=2018e
set -e
rm -rf work

Binary file not shown.

View file

@ -89,6 +89,7 @@ func Test21897(t *testing.T) { test21897(t) }
func Test22906(t *testing.T) { test22906(t) }
func Test24206(t *testing.T) { test24206(t) }
func Test25143(t *testing.T) { test25143(t) }
func Test23356(t *testing.T) { test23356(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }

View file

@ -22,6 +22,10 @@ import (
)
func test18146(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
if runtime.GOOS == "darwin" {
t.Skipf("skipping flaky test on %s; see golang.org/issue/18202", runtime.GOOS)
}
@ -33,10 +37,6 @@ func test18146(t *testing.T) {
attempts := 1000
threads := 4
if testing.Short() {
attempts = 100
}
// Restrict the number of attempts based on RLIMIT_NPROC.
// Tediously, RLIMIT_NPROC was left out of the syscall package,
// probably because it is not in POSIX.1, so we define it here.

View file

@ -0,0 +1,19 @@
// Copyright 2018 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.
package cgotest
// int a(void) { return 5; };
// int r(void) { return 3; };
import "C"
import "testing"
func test23356(t *testing.T) {
if got, want := C.a(), C.int(5); got != want {
t.Errorf("C.a() == %v, expected %v", got, want)
}
if got, want := C.r(), C.int(3); got != want {
t.Errorf("C.r() == %v, expected %v", got, want)
}
}

View file

@ -0,0 +1,11 @@
// Copyright 2018 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.
// Test that we can have two identical cgo packages in a single binary.
// No runtime test; just make sure it compiles.
package cgotest
import _ "./issue23555a"
import _ "./issue23555b"

View file

@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "textflag.h"
package issue23555
TEXT ·startTimer(SB),NOSPLIT,$0
JMP time·startTimer(SB)
// #include <stdlib.h>
import "C"
TEXT ·stopTimer(SB),NOSPLIT,$0
JMP time·stopTimer(SB)
func X() {
C.free(C.malloc(10))
}

View file

@ -0,0 +1,12 @@
// Copyright 2018 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.
package issue23555
// #include <stdlib.h>
import "C"
func X() {
C.free(C.malloc(10))
}

View file

@ -0,0 +1,22 @@
// Copyright 2018 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.
// Test that we can pass compatible typedefs.
// No runtime test; just make sure it compiles.
package cgotest
/*
typedef int *issue23720A;
typedef const int *issue23720B;
void issue23720F(issue23720B a) {}
*/
import "C"
func Issue23720F() {
var x C.issue23720A
C.issue23720F(x)
}

View file

@ -16,6 +16,8 @@ import (
// without writing more assembly code, which we haven't bothered to
// do. So this is not much of a test.
var Baton int32
func RewindAndSetgid() {
atomic.StoreInt32(&Baton, 1)
for atomic.LoadInt32(&Baton) != 0 {

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build gc
package issue9400
var Baton int32

View file

@ -4,10 +4,12 @@
// +build !windows
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
extern void IntoGoAndBack();
@ -28,11 +30,22 @@ static void* sigthreadfunc(void* unused) {
}
int RunSigThread() {
int tries;
pthread_t thread;
int r;
struct timespec ts;
r = pthread_create(&thread, NULL, &sigthreadfunc, NULL);
if (r != 0)
return r;
return pthread_join(thread, NULL);
for (tries = 0; tries < 20; tries++) {
r = pthread_create(&thread, NULL, &sigthreadfunc, NULL);
if (r == 0) {
return pthread_join(thread, NULL);
}
if (r != EAGAIN) {
return r;
}
ts.tv_sec = 0;
ts.tv_nsec = (tries + 1) * 1000 * 1000; // Milliseconds.
nanosleep(&ts, NULL);
}
return EAGAIN;
}

View file

@ -0,0 +1,52 @@
// Copyright 2018 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.
// Run the game of life in C using Go for parallelization.
package main
import (
"flag"
"fmt"
"plugin"
)
const MAXDIM = 100
var dim = flag.Int("dim", 16, "board dimensions")
var gen = flag.Int("gen", 10, "generations")
func main() {
flag.Parse()
var a [MAXDIM * MAXDIM]int32
for i := 2; i < *dim; i += 8 {
for j := 2; j < *dim-3; j += 8 {
for y := 0; y < 3; y++ {
a[i**dim+j+y] = 1
}
}
}
p, err := plugin.Open("life.so")
if err != nil {
panic(err)
}
f, err := p.Lookup("Run")
if err != nil {
panic(err)
}
f.(func(int, int, int, []int32))(*gen, *dim, *dim, a[:])
for i := 0; i < *dim; i++ {
for j := 0; j < *dim; j++ {
if a[i**dim+j] == 0 {
fmt.Print(" ")
} else {
fmt.Print("X")
}
}
fmt.Print("\n")
}
}

View file

@ -0,0 +1,56 @@
// Copyright 2010 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.
#include <assert.h>
#include "life.h"
#include "_cgo_export.h"
const int MYCONST = 0;
// Do the actual manipulation of the life board in C. This could be
// done easily in Go, we are just using C for demonstration
// purposes.
void
Step(int x, int y, int *a, int *n)
{
struct GoStart_return r;
// Use Go to start 4 goroutines each of which handles 1/4 of the
// board.
r = GoStart(0, x, y, 0, x / 2, 0, y / 2, a, n);
assert(r.r0 == 0 && r.r1 == 100); // test multiple returns
r = GoStart(1, x, y, x / 2, x, 0, y / 2, a, n);
assert(r.r0 == 1 && r.r1 == 101); // test multiple returns
GoStart(2, x, y, 0, x / 2, y / 2, y, a, n);
GoStart(3, x, y, x / 2, x, y / 2, y, a, n);
GoWait(0);
GoWait(1);
GoWait(2);
GoWait(3);
}
// The actual computation. This is called in parallel.
void
DoStep(int xdim, int ydim, int xstart, int xend, int ystart, int yend, int *a, int *n)
{
int x, y, c, i, j;
for(x = xstart; x < xend; x++) {
for(y = ystart; y < yend; y++) {
c = 0;
for(i = -1; i <= 1; i++) {
for(j = -1; j <= 1; j++) {
if(x+i >= 0 && x+i < xdim &&
y+j >= 0 && y+j < ydim &&
(i != 0 || j != 0))
c += a[(x+i)*xdim + (y+j)] != 0;
}
}
if(c == 3 || (c == 2 && a[x*xdim + y] != 0))
n[x*xdim + y] = 1;
else
n[x*xdim + y] = 0;
}
}
}

View file

@ -0,0 +1,39 @@
// Copyright 2010 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.
package main
// #include "life.h"
import "C"
import "unsafe"
func Run(gen, x, y int, a []int32) {
n := make([]int32, x*y)
for i := 0; i < gen; i++ {
C.Step(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&a[0])), (*C.int)(unsafe.Pointer(&n[0])))
copy(a, n)
}
}
// Keep the channels visible from Go.
var chans [4]chan bool
//export GoStart
// Double return value is just for testing.
func GoStart(i, xdim, ydim, xstart, xend, ystart, yend C.int, a *C.int, n *C.int) (int, int) {
c := make(chan bool, int(C.MYCONST))
go func() {
C.DoStep(xdim, ydim, xstart, xend, ystart, yend, a, n)
c <- true
}()
chans[i] = c
return int(i), int(i + 100)
}
//export GoWait
func GoWait(i C.int) {
<-chans[i]
chans[i] = nil
}

View file

@ -0,0 +1,7 @@
// Copyright 2010 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.
extern void Step(int, int, int *, int *);
extern void DoStep(int, int, int, int, int, int, int *, int *);
extern const int MYCONST;

View file

@ -15,7 +15,7 @@ goos=$(go env GOOS)
goarch=$(go env GOARCH)
function cleanup() {
rm -f plugin*.so unnamed*.so iface*.so issue*
rm -f plugin*.so unnamed*.so iface*.so life.so issue*
rm -rf host pkg sub iface
}
trap cleanup EXIT
@ -90,3 +90,12 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/m
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue24351.so src/issue24351/plugin.go
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue24351 src/issue24351/main.go
./issue24351
# Test for issue 25756
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o life.so issue25756/plugin
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue25756 src/issue25756/main.go
# Fails intermittently, but 20 runs should cause the failure
for i in `seq 1 20`;
do
./issue25756 > /dev/null
done

View file

@ -7,9 +7,13 @@ package sanitizers_test
import (
"strings"
"testing"
"runtime"
)
func TestTSAN(t *testing.T) {
if runtime.GOARCH == "arm64" {
t.Skip("skipping test; see https://golang.org/issue/25682")
}
t.Parallel()
requireOvercommit(t)
config := configure("thread")

View file

@ -1,4 +1,9 @@
package main
func main() {
// This is enough to make sure that the executable references
// a type descriptor, which was the cause of
// https://golang.org/issue/25970.
c := make(chan int)
_ = c
}

234
misc/wasm/wasm_exec.js Executable file → Normal file
View file

@ -16,13 +16,11 @@
},
};
const now = () => {
const [sec, nsec] = process.hrtime();
return sec * 1000 + nsec / 1000000;
};
global.performance = {
timeOrigin: Date.now() - now(),
now: now,
now() {
const [sec, nsec] = process.hrtime();
return sec * 1000 + nsec / 1000000;
},
};
const util = require("util");
@ -33,7 +31,7 @@
let outputBuf = "";
global.fs = {
constants: {},
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_NONBLOCK: -1, O_SYNC: -1 }, // unused
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
const nl = outputBuf.lastIndexOf("\n");
@ -43,6 +41,11 @@
}
return buf.length;
},
openSync(path, flags, mode) {
const err = new Error("not implemented");
err.code = "ENOSYS";
throw err;
},
};
}
@ -58,6 +61,8 @@
console.warn("exit code:", code);
}
};
this._callbackTimeouts = new Map();
this._nextCallbackTimeoutID = 1;
const mem = () => {
// The buffer may change when requesting more memory.
@ -76,21 +81,72 @@
}
const loadValue = (addr) => {
const f = mem().getFloat64(addr, true);
if (!isNaN(f)) {
return f;
}
const id = mem().getUint32(addr, true);
return this._values[id];
}
const storeValue = (addr, v) => {
if (v === undefined) {
mem().setUint32(addr, 0, true);
if (typeof v === "number") {
if (isNaN(v)) {
mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
mem().setUint32(addr, 0, true);
return;
}
mem().setFloat64(addr, v, true);
return;
}
if (v === null) {
mem().setUint32(addr, 1, true);
mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
switch (v) {
case undefined:
mem().setUint32(addr, 1, true);
return;
case null:
mem().setUint32(addr, 2, true);
return;
case true:
mem().setUint32(addr, 3, true);
return;
case false:
mem().setUint32(addr, 4, true);
return;
}
if (typeof v === "string") {
let ref = this._stringRefs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
this._stringRefs.set(v, ref);
}
mem().setUint32(addr, ref, true);
return;
}
this._values.push(v);
mem().setUint32(addr, this._values.length - 1, true);
if (typeof v === "symbol") {
let ref = this._symbolRefs.get(v);
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
this._symbolRefs.set(v, ref);
}
mem().setUint32(addr, ref, true);
return;
}
let ref = v[this._refProp];
if (ref === undefined) {
ref = this._values.length;
this._values.push(v);
v[this._refProp] = ref;
}
mem().setUint32(addr, ref, true);
}
const loadSlice = (addr) => {
@ -104,8 +160,7 @@
const len = getInt64(addr + 8);
const a = new Array(len);
for (let i = 0; i < len; i++) {
const id = mem().getUint32(array + i * 4, true);
a[i] = this._values[id];
a[i] = loadValue(array + i * 8);
}
return a;
}
@ -116,10 +171,12 @@
return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
}
const timeOrigin = Date.now() - performance.now();
this.importObject = {
go: {
// func wasmExit(code int32)
"runtime.wasmExit": (sp) => {
this.exited = true;
this.exit(mem().getInt32(sp + 8, true));
},
@ -133,7 +190,7 @@
// func nanotime() int64
"runtime.nanotime": (sp) => {
setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000);
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
},
// func walltime() (sec int64, nsec int32)
@ -143,124 +200,117 @@
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
},
// func scheduleCallback(delay int64) int32
"runtime.scheduleCallback": (sp) => {
const id = this._nextCallbackTimeoutID;
this._nextCallbackTimeoutID++;
this._callbackTimeouts.set(id, setTimeout(
() => { this._resolveCallbackPromise(); },
getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early
));
mem().setInt32(sp + 16, id, true);
},
// func clearScheduledCallback(id int32)
"runtime.clearScheduledCallback": (sp) => {
const id = mem().getInt32(sp + 8, true);
clearTimeout(this._callbackTimeouts.get(id));
this._callbackTimeouts.delete(id);
},
// func getRandomData(r []byte)
"runtime.getRandomData": (sp) => {
crypto.getRandomValues(loadSlice(sp + 8));
},
// func boolVal(value bool) Value
"syscall/js.boolVal": (sp) => {
storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
},
// func intVal(value int) Value
"syscall/js.intVal": (sp) => {
storeValue(sp + 16, getInt64(sp + 8));
},
// func floatVal(value float64) Value
"syscall/js.floatVal": (sp) => {
storeValue(sp + 16, mem().getFloat64(sp + 8, true));
},
// func stringVal(value string) Value
// func stringVal(value string) ref
"syscall/js.stringVal": (sp) => {
storeValue(sp + 24, loadString(sp + 8));
},
// func (v Value) Get(key string) Value
"syscall/js.Value.Get": (sp) => {
// func valueGet(v ref, p string) ref
"syscall/js.valueGet": (sp) => {
storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
},
// func (v Value) set(key string, value Value)
"syscall/js.Value.set": (sp) => {
// func valueSet(v ref, p string, x ref)
"syscall/js.valueSet": (sp) => {
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
},
// func (v Value) Index(i int) Value
"syscall/js.Value.Index": (sp) => {
// func valueIndex(v ref, i int) ref
"syscall/js.valueIndex": (sp) => {
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
},
// func (v Value) setIndex(i int, value Value)
"syscall/js.Value.setIndex": (sp) => {
// valueSetIndex(v ref, i int, x ref)
"syscall/js.valueSetIndex": (sp) => {
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
},
// func (v Value) call(name string, args []Value) (Value, bool)
"syscall/js.Value.call": (sp) => {
// func valueCall(v ref, m string, args []ref) (ref, bool)
"syscall/js.valueCall": (sp) => {
try {
const v = loadValue(sp + 8);
const m = Reflect.get(v, loadString(sp + 16));
const args = loadSliceOfValues(sp + 32);
storeValue(sp + 56, Reflect.apply(m, v, args));
mem().setUint8(sp + 60, 1);
mem().setUint8(sp + 64, 1);
} catch (err) {
storeValue(sp + 56, err);
mem().setUint8(sp + 60, 0);
mem().setUint8(sp + 64, 0);
}
},
// func (v Value) invoke(args []Value) (Value, bool)
"syscall/js.Value.invoke": (sp) => {
// func valueInvoke(v ref, args []ref) (ref, bool)
"syscall/js.valueInvoke": (sp) => {
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
storeValue(sp + 40, Reflect.apply(v, undefined, args));
mem().setUint8(sp + 44, 1);
mem().setUint8(sp + 48, 1);
} catch (err) {
storeValue(sp + 40, err);
mem().setUint8(sp + 44, 0);
mem().setUint8(sp + 48, 0);
}
},
// func (v Value) new(args []Value) (Value, bool)
"syscall/js.Value.new": (sp) => {
// func valueNew(v ref, args []ref) (ref, bool)
"syscall/js.valueNew": (sp) => {
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
storeValue(sp + 40, Reflect.construct(v, args));
mem().setUint8(sp + 44, 1);
mem().setUint8(sp + 48, 1);
} catch (err) {
storeValue(sp + 40, err);
mem().setUint8(sp + 44, 0);
mem().setUint8(sp + 48, 0);
}
},
// func (v Value) Float() float64
"syscall/js.Value.Float": (sp) => {
mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
},
// func (v Value) Int() int
"syscall/js.Value.Int": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8)));
},
// func (v Value) Bool() bool
"syscall/js.Value.Bool": (sp) => {
mem().setUint8(sp + 16, !!loadValue(sp + 8));
},
// func (v Value) Length() int
"syscall/js.Value.Length": (sp) => {
// func valueLength(v ref) int
"syscall/js.valueLength": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
},
// func (v Value) prepareString() (Value, int)
"syscall/js.Value.prepareString": (sp) => {
// valuePrepareString(v ref) (ref, int)
"syscall/js.valuePrepareString": (sp) => {
const str = encoder.encode(String(loadValue(sp + 8)));
storeValue(sp + 16, str);
setInt64(sp + 24, str.length);
},
// func (v Value) loadString(b []byte)
"syscall/js.Value.loadString": (sp) => {
// valueLoadString(v ref, b []byte)
"syscall/js.valueLoadString": (sp) => {
const str = loadValue(sp + 8);
loadSlice(sp + 16).set(str);
},
// func valueInstanceOf(v ref, t ref) bool
"syscall/js.valueInstanceOf": (sp) => {
mem().setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16));
},
"debug": (value) => {
console.log(value);
},
@ -270,7 +320,25 @@
async run(instance) {
this._inst = instance;
this._values = [undefined, null, global, this._inst.exports.mem]; // TODO: garbage collection
this._values = [ // TODO: garbage collection
NaN,
undefined,
null,
true,
false,
global,
this._inst.exports.mem,
() => { // resolveCallbackPromise
if (this.exited) {
throw new Error("bad callback: Go program has already exited");
}
setTimeout(this._resolveCallbackPromise, 0); // make sure it is asynchronous
},
];
this._stringRefs = new Map();
this._symbolRefs = new Map();
this._refProp = Symbol();
this.exited = false;
const mem = new DataView(this._inst.exports.mem.buffer)
@ -304,7 +372,16 @@
offset += 8;
});
this._inst.exports.run(argc, argv);
while (true) {
const callbackPromise = new Promise((resolve) => {
this._resolveCallbackPromise = resolve;
});
this._inst.exports.run(argc, argv);
if (this.exited) {
break;
}
await callbackPromise;
}
}
}
@ -319,9 +396,16 @@
go.env = process.env;
go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", () => { // Node.js exits if no callback is pending
if (!go.exited) {
console.error("error: all goroutines asleep and no JavaScript callback pending - deadlock!");
process.exit(1);
}
});
return go.run(result.instance);
}).catch((err) => {
console.error(err);
go.exited = true;
process.exit(1);
});
}

View file

@ -81,9 +81,17 @@ const (
// See the zip spec for details.
type FileHeader struct {
// Name is the name of the file.
// It must be a relative path, not start with a drive letter (e.g. C:),
//
// It must be a relative path, not start with a drive letter (such as "C:"),
// and must use forward slashes instead of back slashes. A trailing slash
// indicates that this file is a directory and should have no data.
//
// When reading zip files, the Name field is populated from
// the zip file directly and is not validated for correctness.
// It is the caller's responsibility to sanitize it as
// appropriate, including canonicalizing slash directions,
// validating that paths are relative, and preventing path
// traversal through filenames ("../../../").
Name string
// Comment is any arbitrary user-defined string shorter than 64KiB.

View file

@ -45,14 +45,19 @@ type Scanner struct {
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
// and the next token to return to the user, if any, plus an error, if any.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
// Scanning stops if the function returns an error, in which case some of
// the input may be discarded.
//
// Otherwise, the Scanner advances the input. If the token is not nil,
// the Scanner returns it to the user. If the token is nil, the
// Scanner reads more data and continues scanning; if there is no more
// data--if atEOF was true--the Scanner returns. If the data does not
// yet hold a complete token, for instance if it has no newline while
// scanning lines, a SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a
// longer slice starting at the same point in the input.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,

View file

@ -77,7 +77,8 @@ func IsARM64STLXR(op obj.As) bool {
arm64.ALDADDB, arm64.ALDADDH, arm64.ALDADDW, arm64.ALDADDD,
arm64.ALDANDB, arm64.ALDANDH, arm64.ALDANDW, arm64.ALDANDD,
arm64.ALDEORB, arm64.ALDEORH, arm64.ALDEORW, arm64.ALDEORD,
arm64.ALDORB, arm64.ALDORH, arm64.ALDORW, arm64.ALDORD:
arm64.ALDORB, arm64.ALDORH, arm64.ALDORW, arm64.ALDORD,
arm64.ALDADDALD, arm64.ALDADDALW:
return true
}
return false

View file

@ -604,6 +604,8 @@ again:
LDORH R5, (RSP), R7 // e7332578
LDORB R5, (R6), R7 // c7302538
LDORB R5, (RSP), R7 // e7332538
LDADDALD R2, (R1), R3 // 2300e2f8
LDADDALW R5, (R4), R6 // 8600e5b8
// RET
//

View file

@ -64,6 +64,11 @@ a full argument: to allow -mfoo=bar, use CGO_CFLAGS_ALLOW='-mfoo.*',
not just CGO_CFLAGS_ALLOW='-mfoo'. Similarly named variables control
the allowed CPPFLAGS, CXXFLAGS, FFLAGS, and LDFLAGS.
Also for security reasons, only a limited set of characters are
permitted, notably alphanumeric characters and a few symbols, such as
'.', that will not be interpreted in unexpected ways. Attempts to use
forbidden characters will get a "malformed #cgo argument" error.
When building, the CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS, CGO_FFLAGS and
CGO_LDFLAGS environment variables are added to the flags derived from
these directives. Package-specific flags should be set using the
@ -223,6 +228,26 @@ C compilers are aware of this calling convention and adjust
the call accordingly, but Go cannot. In Go, you must pass
the pointer to the first element explicitly: C.f(&C.x[0]).
Calling variadic C functions is not supported. It is possible to
circumvent this by using a C function wrapper. For example:
package main
// #include <stdio.h>
// #include <stdlib.h>
//
// static void myprint(char* s) {
// printf("%s\n", s);
// }
import "C"
import "unsafe"
func main() {
cs := C.CString("Hello from stdio")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
A few special functions convert between Go and C types
by making copies of the data. In pseudo-Go definitions:

View file

@ -17,6 +17,7 @@ import (
"go/ast"
"go/printer"
"go/token"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -279,6 +280,7 @@ func main() {
// concern is other cgo wrappers for the same functions.
// Use the beginning of the md5 of the input to disambiguate.
h := md5.New()
io.WriteString(h, *importPath)
fs := make([]*File, len(goFiles))
for i, input := range goFiles {
if *srcDir != "" {

View file

@ -609,14 +609,14 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
// We're trying to write a gcc struct that matches gc's layout.
// Use packed attribute to force no padding in this struct in case
// gcc has different packing requirements.
fmt.Fprintf(fgcc, "\t%s %v *a = v;\n", ctype, p.packedAttribute())
fmt.Fprintf(fgcc, "\t%s %v *_cgo_a = v;\n", ctype, p.packedAttribute())
if n.FuncType.Result != nil {
// Save the stack top for use below.
fmt.Fprintf(fgcc, "\tchar *stktop = _cgo_topofstack();\n")
fmt.Fprintf(fgcc, "\tchar *_cgo_stktop = _cgo_topofstack();\n")
}
tr := n.FuncType.Result
if tr != nil {
fmt.Fprintf(fgcc, "\t__typeof__(a->r) r;\n")
fmt.Fprintf(fgcc, "\t__typeof__(_cgo_a->r) _cgo_r;\n")
}
fmt.Fprintf(fgcc, "\t_cgo_tsan_acquire();\n")
if n.AddError {
@ -624,9 +624,9 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
}
fmt.Fprintf(fgcc, "\t")
if tr != nil {
fmt.Fprintf(fgcc, "r = ")
fmt.Fprintf(fgcc, "_cgo_r = ")
if c := tr.C.String(); c[len(c)-1] == '*' {
fmt.Fprint(fgcc, "(__typeof__(a->r)) ")
fmt.Fprint(fgcc, "(__typeof__(_cgo_a->r)) ")
}
}
if n.Kind == "macro" {
@ -637,7 +637,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
if i > 0 {
fmt.Fprintf(fgcc, ", ")
}
fmt.Fprintf(fgcc, "a->p%d", i)
fmt.Fprintf(fgcc, "_cgo_a->p%d", i)
}
fmt.Fprintf(fgcc, ");\n")
}
@ -648,9 +648,9 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
if n.FuncType.Result != nil {
// The cgo call may have caused a stack copy (via a callback).
// Adjust the return value pointer appropriately.
fmt.Fprintf(fgcc, "\ta = (void*)((char*)a + (_cgo_topofstack() - stktop));\n")
fmt.Fprintf(fgcc, "\t_cgo_a = (void*)((char*)_cgo_a + (_cgo_topofstack() - _cgo_stktop));\n")
// Save the return value.
fmt.Fprintf(fgcc, "\ta->r = r;\n")
fmt.Fprintf(fgcc, "\t_cgo_a->r = _cgo_r;\n")
}
if n.AddError {
fmt.Fprintf(fgcc, "\treturn _cgo_errno;\n")
@ -685,12 +685,12 @@ func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
fmt.Fprintf(fgcc, ")\n")
fmt.Fprintf(fgcc, "{\n")
if t := n.FuncType.Result; t != nil {
fmt.Fprintf(fgcc, "\t%s r;\n", t.C.String())
fmt.Fprintf(fgcc, "\t%s _cgo_r;\n", t.C.String())
}
fmt.Fprintf(fgcc, "\t_cgo_tsan_acquire();\n")
fmt.Fprintf(fgcc, "\t")
if t := n.FuncType.Result; t != nil {
fmt.Fprintf(fgcc, "r = ")
fmt.Fprintf(fgcc, "_cgo_r = ")
// Cast to void* to avoid warnings due to omitted qualifiers.
if c := t.C.String(); c[len(c)-1] == '*' {
fmt.Fprintf(fgcc, "(void*)")
@ -716,7 +716,7 @@ func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
if c := t.C.String(); c[len(c)-1] == '*' {
fmt.Fprintf(fgcc, "(void*)")
}
fmt.Fprintf(fgcc, "r;\n")
fmt.Fprintf(fgcc, "_cgo_r;\n")
}
fmt.Fprintf(fgcc, "}\n")
fmt.Fprintf(fgcc, "\n")

View file

@ -26,7 +26,7 @@ little to do with uppercase GC, which stands for garbage collection.
* `cmd/compile/internal/syntax` (lexer, parser, syntax tree)
In the first phase of compilation, source code is tokenized (lexical analysis),
parsed (syntactic analyses), and a syntax tree is constructed for each source
parsed (syntax analysis), and a syntax tree is constructed for each source
file.
Each syntax tree is an exact representation of the respective source file, with

View file

@ -553,6 +553,28 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p3.From.Reg = arm64.REGTMP
p3.To.Type = obj.TYPE_BRANCH
gc.Patch(p3, p)
case ssa.OpARM64LoweredAtomicAdd64Variant,
ssa.OpARM64LoweredAtomicAdd32Variant:
// LDADDAL Rarg1, (Rarg0), Rout
// ADD Rarg1, Rout
op := arm64.ALDADDALD
if v.Op == ssa.OpARM64LoweredAtomicAdd32Variant {
op = arm64.ALDADDALW
}
r0 := v.Args[0].Reg()
r1 := v.Args[1].Reg()
out := v.Reg0()
p := s.Prog(op)
p.From.Type = obj.TYPE_REG
p.From.Reg = r1
p.To.Type = obj.TYPE_MEM
p.To.Reg = r0
p.RegTo2 = out
p1 := s.Prog(arm64.AADD)
p1.From.Type = obj.TYPE_REG
p1.From.Reg = r1
p1.To.Type = obj.TYPE_REG
p1.To.Reg = out
case ssa.OpARM64LoweredAtomicCas64,
ssa.OpARM64LoweredAtomicCas32:
// LDAXR (Rarg0), Rtmp
@ -603,25 +625,26 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
gc.Patch(p2, p5)
case ssa.OpARM64LoweredAtomicAnd8,
ssa.OpARM64LoweredAtomicOr8:
// LDAXRB (Rarg0), Rtmp
// AND/OR Rarg1, Rtmp
// STLXRB Rtmp, (Rarg0), Rtmp
// LDAXRB (Rarg0), Rout
// AND/OR Rarg1, Rout
// STLXRB Rout, (Rarg0), Rtmp
// CBNZ Rtmp, -3(PC)
r0 := v.Args[0].Reg()
r1 := v.Args[1].Reg()
out := v.Reg0()
p := s.Prog(arm64.ALDAXRB)
p.From.Type = obj.TYPE_MEM
p.From.Reg = r0
p.To.Type = obj.TYPE_REG
p.To.Reg = arm64.REGTMP
p.To.Reg = out
p1 := s.Prog(v.Op.Asm())
p1.From.Type = obj.TYPE_REG
p1.From.Reg = r1
p1.To.Type = obj.TYPE_REG
p1.To.Reg = arm64.REGTMP
p1.To.Reg = out
p2 := s.Prog(arm64.ASTLXRB)
p2.From.Type = obj.TYPE_REG
p2.From.Reg = arm64.REGTMP
p2.From.Reg = out
p2.To.Type = obj.TYPE_MEM
p2.To.Reg = r0
p2.RegTo2 = arm64.REGTMP

View file

@ -1128,16 +1128,20 @@ func (p *exporter) stmtList(list Nodes) {
}
// TODO inlining produces expressions with ninits. we can't export these yet.
// (from fmt.go:1461ff)
if opprec[n.Op] < 0 {
p.stmt(n)
} else {
p.expr(n)
}
p.node(n)
}
p.op(OEND)
}
func (p *exporter) node(n *Node) {
if opprec[n.Op] < 0 {
p.stmt(n)
} else {
p.expr(n)
}
}
func (p *exporter) exprList(list Nodes) {
if p.trace {
if list.Len() == 0 {
@ -1552,7 +1556,7 @@ func (p *exporter) exprsOrNil(a, b *Node) {
p.expr(a)
}
if ab&2 != 0 {
p.expr(b)
p.node(b)
}
}

View file

@ -1209,7 +1209,7 @@ func (p *importer) exprsOrNil() (a, b *Node) {
a = p.expr()
}
if ab&2 != 0 {
b = p.expr()
b = p.node()
}
return
}

View file

@ -141,6 +141,7 @@ var runtimeDecls = [...]struct {
{"uint32tofloat64", funcTag, 109},
{"complex128div", funcTag, 110},
{"racefuncenter", funcTag, 111},
{"racefuncenterfp", funcTag, 5},
{"racefuncexit", funcTag, 5},
{"raceread", funcTag, 111},
{"racewrite", funcTag, 111},

View file

@ -183,6 +183,7 @@ func complex128div(num complex128, den complex128) (quo complex128)
// race detection
func racefuncenter(uintptr)
func racefuncenterfp()
func racefuncexit()
func raceread(uintptr)
func racewrite(uintptr)

View file

@ -243,15 +243,20 @@ func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
n.Type = t
}
if n.Type.Etype == TIDEAL {
n.Left = convlit(n.Left, t)
n.Right = convlit(n.Right, t)
n.Type = t
if n.Type.IsUntyped() {
if t.IsInterface() {
n.Left, n.Right = defaultlit2(n.Left, n.Right, true)
n.Type = n.Left.Type // same as n.Right.Type per defaultlit2
} else {
n.Left = convlit(n.Left, t)
n.Right = convlit(n.Right, t)
n.Type = t
}
}
return n
// target is invalid type for a constant? leave alone.
// target is invalid type for a constant? leave alone.
case OLITERAL:
if !okforconst[t.Etype] && n.Type.Etype != TNIL {
return defaultlitreuse(n, nil, reuse)
@ -294,7 +299,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
return n
}
// avoided repeated calculations, errors
// avoid repeated calculations, errors
if eqtype(n.Type, t) {
return n
}
@ -1266,7 +1271,6 @@ func idealkind(n *Node) Ctype {
OOR,
OPLUS:
k1 := idealkind(n.Left)
k2 := idealkind(n.Right)
if k1 > k2 {
return k1

View file

@ -151,22 +151,27 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 {
// Escape analysis.
// An escape analysis pass for a set of functions.
// The analysis assumes that closures and the functions in which they
// appear are analyzed together, so that the aliasing between their
// variables can be modeled more precisely.
// An escape analysis pass for a set of functions. The
// analysis assumes that closures and the functions in which
// they appear are analyzed together, so that the aliasing
// between their variables can be modeled more precisely.
//
// First escfunc, esc and escassign recurse over the ast of each
// function to dig out flow(dst,src) edges between any
// pointer-containing nodes and store them in e.nodeEscState(dst).Flowsrc. For
// variables assigned to a variable in an outer scope or used as a
// return value, they store a flow(theSink, src) edge to a fake node
// 'the Sink'. For variables referenced in closures, an edge
// flow(closure, &var) is recorded and the flow of a closure itself to
// an outer scope is tracked the same way as other variables.
// First escfunc, esc and escassign recurse over the ast of
// each function to dig out flow(dst,src) edges between any
// pointer-containing nodes and store those edges in
// e.nodeEscState(dst).Flowsrc. For values assigned to a
// variable in an outer scope or used as a return value,
// they store a flow(theSink, src) edge to a fake node 'the
// Sink'. For variables referenced in closures, an edge
// flow(closure, &var) is recorded and the flow of a closure
// itself to an outer scope is tracked the same way as other
// variables.
//
// Then escflood walks the graph starting at theSink and tags all
// variables of it can reach an & node as escaping and all function
// Then escflood walks the graph in destination-to-source
// order, starting at theSink, propagating a computed
// "escape level", and tags as escaping values it can
// reach that are either & (address-taken) nodes or new(T),
// and tags pointer-typed or pointer-containing function
// parameters it can reach as leaking.
//
// If a value's address is taken but the address does not escape,
@ -185,19 +190,6 @@ const (
EscFuncTagged
)
// There appear to be some loops in the escape graph, causing
// arbitrary recursion into deeper and deeper levels.
// Cut this off safely by making minLevel sticky: once you
// get that deep, you cannot go down any further but you also
// cannot go up any further. This is a conservative fix.
// Making minLevel smaller (more negative) would handle more
// complex chains of indirections followed by address-of operations,
// at the cost of repeating the traversal once for each additional
// allowed level when a loop is encountered. Using -2 suffices to
// pass all the tests we have written so far, which we assume matches
// the level of complexity we want the escape analysis code to handle.
const MinLevel = -2
// A Level encodes the reference state and context applied to
// (stack, heap) allocated memory.
//
@ -205,21 +197,49 @@ const MinLevel = -2
// along a path from a destination (sink, return value) to a source
// (allocation, parameter).
//
// suffixValue is the maximum-copy-started-suffix-level applied to a sink.
// For example:
// sink = x.left.left --> level=2, x is dereferenced twice and does not escape to sink.
// sink = &Node{x} --> level=-1, x is accessible from sink via one "address of"
// sink = &Node{&Node{x}} --> level=-2, x is accessible from sink via two "address of"
// sink = &Node{&Node{x.left}} --> level=-1, but x is NOT accessible from sink because it was indirected and then copied.
// (The copy operations are sometimes implicit in the source code; in this case,
// value of x.left was copied into a field of a newly allocated Node)
// suffixValue is the maximum-copy-started-suffix-level on
// a flow path from a sink/destination. That is, a value
// with suffixValue N is guaranteed to be dereferenced at least
// N deep (chained applications of DOTPTR or IND or INDEX)
// before the result is assigned to a sink.
//
// For example, suppose x is a pointer to T, declared type T struct { left, right *T }
// sink = x.left.left --> level(x)=2, x is reached via two dereferences (DOTPTR) and does not escape to sink.
// sink = &T{right:x} --> level(x)=-1, x is accessible from sink via one "address of"
// sink = &T{right:&T{right:x}} --> level(x)=-2, x is accessible from sink via two "address of"
//
// However, in the next example x's level value and suffixValue differ:
// sink = &T{right:&T{right:x.left}} --> level(x).value=-1, level(x).suffixValue=1
// The positive suffixValue indicates that x is NOT accessible
// from sink. Without a separate suffixValue to capture this, x would
// appear to escape because its "value" would be -1. (The copy
// operations are sometimes implicit in the source code; in this case,
// the value of x.left was copied into a field of an newly allocated T).
//
// Each node's level (value and suffixValue) is the maximum for
// all flow paths from (any) sink to that node.
// There's one of these for each Node, and the integer values
// rarely exceed even what can be stored in 4 bits, never mind 8.
type Level struct {
value, suffixValue int8
}
// There are loops in the escape graph,
// causing arbitrary recursion into deeper and deeper
// levels. Cut this off safely by making minLevel sticky:
// once you get that deep, you cannot go down any further
// but you also cannot go up any further. This is a
// conservative fix. Making minLevel smaller (more negative)
// would handle more complex chains of indirections followed
// by address-of operations, at the cost of repeating the
// traversal once for each additional allowed level when a
// loop is encountered. Using -2 suffices to pass all the
// tests we have written so far, which we assume matches the
// level of complexity we want the escape analysis code to
// handle.
const MinLevel = -2
func (l Level) int() int {
return int(l.value)
}
@ -269,6 +289,7 @@ func (l Level) dec() Level {
}
// copy returns the level for a copy of a value with level l.
// The resulting suffixValue is at least zero, or larger if it was already larger.
func (l Level) copy() Level {
return Level{value: l.value, suffixValue: max8(l.suffixValue, 0)}
}

View file

@ -89,7 +89,7 @@ func dumpexport(bout *bio.Writer) {
}
func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
n := asNode(s.Def)
n := asNode(s.PkgDef())
if n == nil {
// iimport should have created a stub ONONAME
// declaration for all imported symbols. The exception
@ -100,7 +100,7 @@ func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
}
n = dclname(s)
s.Def = asTypesNode(n)
s.SetPkgDef(asTypesNode(n))
s.Importdef = ipkg
}
if n.Op != ONONAME && n.Op != op {

View file

@ -303,6 +303,7 @@ var (
racewriterange,
supportPopcnt,
supportSSE41,
arm64SupportAtomics,
typedmemclr,
typedmemmove,
Udiv,

View file

@ -970,15 +970,19 @@ func (w *exportWriter) linkname(s *types.Sym) {
func (w *exportWriter) stmtList(list Nodes) {
for _, n := range list.Slice() {
if opprec[n.Op] < 0 {
w.stmt(n)
} else {
w.expr(n)
}
w.node(n)
}
w.op(OEND)
}
func (w *exportWriter) node(n *Node) {
if opprec[n.Op] < 0 {
w.stmt(n)
} else {
w.expr(n)
}
}
// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
func (w *exportWriter) stmt(n *Node) {
@ -1338,7 +1342,7 @@ func (w *exportWriter) exprsOrNil(a, b *Node) {
w.expr(a)
}
if ab&2 != 0 {
w.expr(b)
w.node(b)
}
}

View file

@ -46,9 +46,7 @@ func expandDecl(n *Node) {
return
}
inimport = true
r.doDecl(n)
inimport = false
}
func expandInline(fn *Node) {
@ -1060,7 +1058,7 @@ func (r *importReader) exprsOrNil() (a, b *Node) {
a = r.expr()
}
if ab&2 != 0 {
b = r.expr()
b = r.node()
}
return
}

View file

@ -132,6 +132,12 @@ func caninl(fn *Node) {
return
}
// If marked "go:norace" and -race compilation, don't inline.
if flag_race && fn.Func.Pragma&Norace != 0 {
reason = "marked go:norace with -race compilation"
return
}
// If marked "go:cgo_unsafe_args", don't inline, since the
// function makes assumptions about its argument frame layout.
if fn.Func.Pragma&CgoUnsafeArgs != 0 {

View file

@ -481,15 +481,13 @@ func Main(archInit func(*Arch)) {
// Phase 1: const, type, and names and types of funcs.
// This will gather all the information about types
// and methods but doesn't depend on any of it.
// We also defer type alias declarations until phase 2
// to avoid cycles like #18640.
defercheckwidth()
// Don't use range--typecheck can add closures to xtop.
timings.Start("fe", "typecheck", "top1")
for i := 0; i < len(xtop); i++ {
n := xtop[i]
if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias) {
if op := n.Op; op != ODCL && op != OAS && op != OAS2 {
xtop[i] = typecheck(n, Etop)
}
}
@ -501,7 +499,7 @@ func Main(archInit func(*Arch)) {
timings.Start("fe", "typecheck", "top2")
for i := 0; i < len(xtop); i++ {
n := xtop[i]
if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias {
if op := n.Op; op == ODCL || op == OAS || op == OAS2 {
xtop[i] = typecheck(n, Etop)
}
}

View file

@ -19,6 +19,10 @@ import (
"cmd/internal/src"
)
// parseFiles concurrently parses files into *syntax.File structures.
// Each declaration in every *syntax.File is converted to a syntax tree
// and its root represented by *Node is appended to xtop.
// Returns the total count of parsed lines.
func parseFiles(filenames []string) uint {
var noders []*noder
// Limit the number of simultaneously open files.

View file

@ -7,6 +7,7 @@ package gc
import (
"cmd/compile/internal/types"
"cmd/internal/src"
"cmd/internal/sys"
)
// The racewalk pass is currently handled in two parts.
@ -58,17 +59,23 @@ func instrument(fn *Node) {
lno := lineno
lineno = src.NoXPos
// nodpc is the PC of the caller as extracted by
// getcallerpc. We use -widthptr(FP) for x86.
// BUG: this will not work on arm.
nodpc := nodfp.copy()
nodpc.Type = types.Types[TUINTPTR]
nodpc.Xoffset = int64(-Widthptr)
fn.Func.Dcl = append(fn.Func.Dcl, nodpc)
fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
if thearch.LinkArch.Arch == sys.ArchPPC64LE {
fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
} else {
// nodpc is the PC of the caller as extracted by
// getcallerpc. We use -widthptr(FP) for x86.
// BUG: This only works for amd64. This will not
// work on arm or others that might support
// race in the future.
nodpc := nodfp.copy()
nodpc.Type = types.Types[TUINTPTR]
nodpc.Xoffset = int64(-Widthptr)
fn.Func.Dcl = append(fn.Func.Dcl, nodpc)
fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
}
lineno = lno
}
}

View file

@ -33,7 +33,15 @@ func typecheckselect(sel *Node) {
ncase.List.Set(nil)
switch n.Op {
default:
yyerrorl(n.Pos, "select case must be receive, send or assign recv")
pos := n.Pos
if n.Op == ONAME {
// We don't have the right position for ONAME nodes (see #15459 and
// others). Using ncase.Pos for now as it will provide the correct
// line number (assuming the expression follows the "case" keyword
// on the same line). This matches the approach before 1.10.
pos = ncase.Pos
}
yyerrorl(pos, "select case must be receive, send or assign recv")
// convert x = <-c into OSELRECV(x, <-c).
// remove implicit conversions; the eventual assignment

View file

@ -78,6 +78,7 @@ func initssaconfig() {
racewriterange = sysfunc("racewriterange")
supportPopcnt = sysfunc("support_popcnt")
supportSSE41 = sysfunc("support_sse41")
arm64SupportAtomics = sysfunc("arm64_support_atomics")
typedmemclr = sysfunc("typedmemclr")
typedmemmove = sysfunc("typedmemmove")
Udiv = sysfunc("udiv")
@ -2169,8 +2170,9 @@ func (s *state) expr(n *Node) *ssa.Value {
p := s.addr(n, false)
return s.load(n.Left.Type.Elem(), p)
case n.Left.Type.IsArray():
if bound := n.Left.Type.NumElem(); bound <= 1 {
if canSSAType(n.Left.Type) {
// SSA can handle arrays of length at most 1.
bound := n.Left.Type.NumElem()
a := s.expr(n.Left)
i := s.expr(n.Right)
if bound == 0 {
@ -2935,14 +2937,56 @@ func init() {
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
},
sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
sys.AMD64, sys.S390X, sys.MIPS, sys.MIPS64, sys.PPC64)
addF("runtime/internal/atomic", "Xadd64",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem())
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
},
sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS64, sys.PPC64)
sys.AMD64, sys.S390X, sys.MIPS64, sys.PPC64)
makeXaddARM64 := func(op0 ssa.Op, op1 ssa.Op, ty types.EType) func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
// Target Atomic feature is identified by dynamic detection
addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), arm64SupportAtomics, s.sb)
v := s.load(types.Types[TBOOL], addr)
b := s.endBlock()
b.Kind = ssa.BlockIf
b.SetControl(v)
bTrue := s.f.NewBlock(ssa.BlockPlain)
bFalse := s.f.NewBlock(ssa.BlockPlain)
bEnd := s.f.NewBlock(ssa.BlockPlain)
b.AddEdgeTo(bTrue)
b.AddEdgeTo(bFalse)
b.Likely = ssa.BranchUnlikely // most machines don't have Atomics nowadays
// We have atomic instructions - use it directly.
s.startBlock(bTrue)
v0 := s.newValue3(op1, types.NewTuple(types.Types[ty], types.TypeMem), args[0], args[1], s.mem())
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v0)
s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[ty], v0)
s.endBlock().AddEdgeTo(bEnd)
// Use original instruction sequence.
s.startBlock(bFalse)
v1 := s.newValue3(op0, types.NewTuple(types.Types[ty], types.TypeMem), args[0], args[1], s.mem())
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v1)
s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[ty], v1)
s.endBlock().AddEdgeTo(bEnd)
// Merge results.
s.startBlock(bEnd)
return s.variable(n, types.Types[ty])
}
}
addF("runtime/internal/atomic", "Xadd",
makeXaddARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, TUINT32),
sys.ARM64)
addF("runtime/internal/atomic", "Xadd64",
makeXaddARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, TUINT64),
sys.ARM64)
addF("runtime/internal/atomic", "Cas",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
@ -4985,7 +5029,7 @@ func genssa(f *ssa.Func, pp *Progs) {
}
buf.WriteString("</dl>")
buf.WriteString("</code>")
f.HTMLWriter.WriteColumn("genssa", "ssa-prog", buf.String())
f.HTMLWriter.WriteColumn("genssa", "genssa", "ssa-prog", buf.String())
// pp.Text.Ctxt.LineHist.PrintFilenameOnly = saved
}
}

View file

@ -241,6 +241,11 @@ func walkswitch(sw *Node) {
// search using if..goto, although binary search
// is used with long runs of constants.
func (s *exprSwitch) walk(sw *Node) {
// Guard against double walk, see #25776.
if sw.List.Len() == 0 && sw.Nbody.Len() > 0 {
Fatalf("second walk of switch")
}
casebody(sw, nil)
cond := sw.Left

View file

@ -37,7 +37,12 @@ func resolve(n *Node) *Node {
}
if n.Sym.Pkg != localpkg {
if inimport {
Fatalf("recursive inimport")
}
inimport = true
expandDecl(n)
inimport = false
return n
}
@ -110,19 +115,35 @@ func typekind(t *types.Type) string {
return fmt.Sprintf("etype=%d", et)
}
// sprint_depchain prints a dependency chain of nodes into trace.
// It is used by typecheck in the case of OLITERAL nodes
// to print constant definition loops.
func sprint_depchain(trace *string, stack []*Node, cur *Node, first *Node) {
for i := len(stack) - 1; i >= 0; i-- {
if n := stack[i]; n.Op == cur.Op {
if n != first {
sprint_depchain(trace, stack[:i], n, first)
}
*trace += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cur)
return
func cycleFor(start *Node) []*Node {
// Find the start node in typecheck_tcstack.
// We know that it must exist because each time we mark
// a node with n.SetTypecheck(2) we push it on the stack,
// and each time we mark a node with n.SetTypecheck(2) we
// pop it from the stack. We hit a cycle when we encounter
// a node marked 2 in which case is must be on the stack.
i := len(typecheck_tcstack) - 1
for i > 0 && typecheck_tcstack[i] != start {
i--
}
// collect all nodes with same Op
var cycle []*Node
for _, n := range typecheck_tcstack[i:] {
if n.Op == start.Op {
cycle = append(cycle, n)
}
}
return cycle
}
func cycleTrace(cycle []*Node) string {
var s string
for i, n := range cycle {
s += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cycle[(i+1)%len(cycle)])
}
return s
}
var typecheck_tcstack []*Node
@ -174,10 +195,20 @@ func typecheck(n *Node, top int) *Node {
}
case OTYPE:
// Only report a type cycle if we are expecting a type.
// Otherwise let other code report an error.
if top&Etype == Etype {
var trace string
sprint_depchain(&trace, typecheck_tcstack, n, n)
yyerrorl(n.Pos, "invalid recursive type alias %v%s", n, trace)
// A cycle containing only alias types is an error
// since it would expand indefinitely when aliases
// are substituted.
cycle := cycleFor(n)
for _, n := range cycle {
if n.Name != nil && !n.Name.Param.Alias {
lineno = lno
return n
}
}
yyerrorl(n.Pos, "invalid recursive type alias %v%s", n, cycleTrace(cycle))
}
case OLITERAL:
@ -185,9 +216,7 @@ func typecheck(n *Node, top int) *Node {
yyerror("%v is not a type", n)
break
}
var trace string
sprint_depchain(&trace, typecheck_tcstack, n, n)
yyerrorl(n.Pos, "constant definition loop%s", trace)
yyerrorl(n.Pos, "constant definition loop%s", cycleTrace(cycleFor(n)))
}
if nsavederrors+nerrors == 0 {
@ -895,7 +924,7 @@ func typecheck1(n *Node, top int) *Node {
yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym)
default:
if mt := lookdot(n, t, 2); mt != nil { // Case-insensitive lookup.
if mt := lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup.
yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym)
} else {
yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym)
@ -3108,7 +3137,11 @@ func typecheckcomplit(n *Node) *Node {
f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
if f == nil {
if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
if visible(ci.Sym) {
yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
} else {
yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
}
continue
}
p, _ := dotpath(l.Sym, t, nil, true)
@ -3155,6 +3188,11 @@ func typecheckcomplit(n *Node) *Node {
return n
}
// visible reports whether sym is exported or locally defined.
func visible(sym *types.Sym) bool {
return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == localpkg)
}
// lvalue etc
func islvalue(n *Node) bool {
switch n.Op {

View file

@ -287,7 +287,6 @@ func walkstmt(n *Node) *Node {
walkstmtlist(n.Rlist.Slice())
case ORETURN:
walkexprlist(n.List.Slice(), &n.Ninit)
if n.List.Len() == 0 {
break
}
@ -317,6 +316,9 @@ func walkstmt(n *Node) *Node {
if samelist(rl, n.List.Slice()) {
// special return in disguise
// TODO(josharian, 1.12): is "special return" still relevant?
// Tests still pass w/o this. See comments on https://go-review.googlesource.com/c/go/+/118318
walkexprlist(n.List.Slice(), &n.Ninit)
n.List.Set(nil)
break
@ -329,6 +331,7 @@ func walkstmt(n *Node) *Node {
n.List.Set(reorder3(ll))
break
}
walkexprlist(n.List.Slice(), &n.Ninit)
ll := ascompatte(nil, false, Curfn.Type.Results(), n.List.Slice(), 1, &n.Ninit)
n.List.Set(ll)

View file

@ -43,7 +43,7 @@ func Compile(f *Func) {
// Run all the passes
printFunc(f)
f.HTMLWriter.WriteFunc("start", f)
f.HTMLWriter.WriteFunc("start", "start", f)
if BuildDump != "" && BuildDump == f.Name {
f.dumpFile("build")
}
@ -86,7 +86,7 @@ func Compile(f *Func) {
f.Logf(" pass %s end %s\n", p.name, stats)
printFunc(f)
f.HTMLWriter.WriteFunc(fmt.Sprintf("after %s <span class=\"stats\">%s</span>", phaseName, stats), f)
f.HTMLWriter.WriteFunc(phaseName, fmt.Sprintf("%s <span class=\"stats\">%s</span>", phaseName, stats), f)
}
if p.time || p.mem {
// Surround timing information w/ enough context to allow comparisons.

View file

@ -397,11 +397,11 @@ func init() {
{name: "CMOVQNEF", argLength: 3, reg: gp21, asm: "CMOVQNE", resultInArg0: true},
{name: "CMOVQGTF", argLength: 3, reg: gp21, asm: "CMOVQHI", resultInArg0: true},
{name: "CMOVQGEF", argLength: 3, reg: gp21, asm: "CMOVQCC", resultInArg0: true},
{name: "CMOVLEQF", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true},
{name: "CMOVLEQF", argLength: 3, reg: gp21pax, asm: "CMOVLNE", resultInArg0: true},
{name: "CMOVLNEF", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true},
{name: "CMOVLGTF", argLength: 3, reg: gp21, asm: "CMOVLHI", resultInArg0: true},
{name: "CMOVLGEF", argLength: 3, reg: gp21, asm: "CMOVLCC", resultInArg0: true},
{name: "CMOVWEQF", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true},
{name: "CMOVWEQF", argLength: 3, reg: gp21pax, asm: "CMOVWNE", resultInArg0: true},
{name: "CMOVWNEF", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true},
{name: "CMOVWGTF", argLength: 3, reg: gp21, asm: "CMOVWHI", resultInArg0: true},
{name: "CMOVWGEF", argLength: 3, reg: gp21, asm: "CMOVWCC", resultInArg0: true},

View file

@ -829,14 +829,14 @@
(RSBconst [c] (SUBconst [d] x)) -> (RSBconst [int64(int32(c+d))] x)
(RSCconst [c] (ADDconst [d] x) flags) -> (RSCconst [int64(int32(c-d))] x flags)
(RSCconst [c] (SUBconst [d] x) flags) -> (RSCconst [int64(int32(c+d))] x flags)
(SLLconst [c] (MOVWconst [d])) -> (MOVWconst [int64(uint32(d)<<uint64(c))])
(SRLconst [c] (MOVWconst [d])) -> (MOVWconst [int64(uint32(d)>>uint64(c))])
(SLLconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(uint32(d)<<uint64(c)))])
(SRLconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(uint32(d)>>uint64(c)))])
(SRAconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)>>uint64(c))])
(MUL (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(int32(c*d))])
(MULA (MOVWconst [c]) (MOVWconst [d]) a) -> (ADDconst [int64(int32(c*d))] a)
(MULS (MOVWconst [c]) (MOVWconst [d]) a) -> (SUBconst [int64(int32(c*d))] a)
(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)/uint32(d))])
(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)%uint32(d))])
(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(int32(uint32(c)/uint32(d)))])
(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(int32(uint32(c)%uint32(d)))])
(ANDconst [c] (MOVWconst [d])) -> (MOVWconst [c&d])
(ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c&d] x)
(ORconst [c] (MOVWconst [d])) -> (MOVWconst [c|d])
@ -853,7 +853,7 @@
(MOVWreg (MOVWconst [c])) -> (MOVWconst [c])
// BFX: Width = c >> 8, LSB = c & 0xff, result = d << (32 - Width - LSB) >> (32 - Width)
(BFX [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
(BFXU [c] (MOVWconst [d])) -> (MOVWconst [int64(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
(BFXU [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))))])
// absorb shifts into ops
(ADD x (SLLconst [c] y)) -> (ADDshiftLL x y [c])

View file

@ -540,8 +540,12 @@
(AtomicCompareAndSwap32 ptr old new_ mem) -> (LoweredAtomicCas32 ptr old new_ mem)
(AtomicCompareAndSwap64 ptr old new_ mem) -> (LoweredAtomicCas64 ptr old new_ mem)
(AtomicAnd8 ptr val mem) -> (LoweredAtomicAnd8 ptr val mem)
(AtomicOr8 ptr val mem) -> (LoweredAtomicOr8 ptr val mem)
// Currently the updated value is not used, but we need a register to temporarily hold it.
(AtomicAnd8 ptr val mem) -> (Select1 (LoweredAtomicAnd8 ptr val mem))
(AtomicOr8 ptr val mem) -> (Select1 (LoweredAtomicOr8 ptr val mem))
(AtomicAdd32Variant ptr val mem) -> (LoweredAtomicAdd32Variant ptr val mem)
(AtomicAdd64Variant ptr val mem) -> (LoweredAtomicAdd64Variant ptr val mem)
// Write barrier.
(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem)

View file

@ -578,6 +578,13 @@ func init() {
{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
// atomic add variant.
// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
// LDADDAL (Rarg0), Rarg1, Rout
// ADD Rarg1, Rout
{name: "LoweredAtomicAdd64Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicAdd32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
// atomic compare and swap.
// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
// if *arg0 == arg1 {
@ -596,13 +603,13 @@ func init() {
{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
// atomic and/or.
// *arg0 &= (|=) arg1. arg2=mem. returns memory. auxint must be zero.
// LDAXRB (Rarg0), Rtmp
// AND/OR Rarg1, Rtmp
// STLXRB Rtmp, (Rarg0), Rtmp
// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
// LDAXRB (Rarg0), Rout
// AND/OR Rarg1, Rout
// STLXRB Rout, (Rarg0), Rtmp
// CBNZ Rtmp, -3(PC)
{name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "ORR", faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true},
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
// It saves all GP registers if necessary,

View file

@ -390,6 +390,7 @@
(I64AddConst [0] x) -> x
(I64Eqz (I64Eqz (I64Eqz x))) -> (I64Eqz x)
// folding offset into load/store
((I64Load|I64Load32U|I64Load32S|I64Load16U|I64Load16S|I64Load8U|I64Load8S) [off] (I64AddConst [off2] ptr) mem)
&& isU32Bit(off+off2) ->
((I64Load|I64Load32U|I64Load32S|I64Load16U|I64Load16S|I64Load8U|I64Load8S) [off+off2] ptr mem)
@ -397,3 +398,7 @@
((I64Store|I64Store32|I64Store16|I64Store8) [off] (I64AddConst [off2] ptr) val mem)
&& isU32Bit(off+off2) ->
((I64Store|I64Store32|I64Store16|I64Store8) [off+off2] ptr val mem)
// folding offset into address
(I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+off2) ->
(LoweredAddr {sym} [off+off2] base)

View file

@ -103,7 +103,7 @@ func init() {
{name: "LoweredClosureCall", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp, 0}, clobbers: callerSave}, aux: "Int64", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
{name: "LoweredInterCall", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
{name: "LoweredAddr", argLength: 1, reg: gp11, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // returns base+aux, arg0=base
{name: "LoweredAddr", argLength: 1, reg: gp11, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // returns base+aux+auxint, arg0=base
{name: "LoweredMove", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Int64"}, // large move. arg0=dst, arg1=src, arg2=mem, auxint=len/8, returns mem
{name: "LoweredZero", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, aux: "Int64"}, // large zeroing. arg0=start, arg1=mem, auxint=len/8, returns mem

View file

@ -515,6 +515,13 @@ var genericOps = []opData{
{name: "AtomicAnd8", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 &= arg1. arg2=memory. Returns memory.
{name: "AtomicOr8", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory.
// Atomic operation variants
// These variants have the same semantics as above atomic operations.
// But they are used for generating more efficient code on certain modern machines, with run-time CPU feature detection.
// Currently, they are used on ARM64 only.
{name: "AtomicAdd32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
{name: "AtomicAdd64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
// Clobber experiment op
{name: "Clobber", argLength: 0, typ: "Void", aux: "SymOff", symEffect: "None"}, // write an invalid pointer value to the given pointer slot of a stack variable
}

View file

@ -38,6 +38,11 @@ func (w *HTMLWriter) start(name string) {
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<style>
body {
font-size: 14px;
font-family: Arial, sans-serif;
}
#helplink {
margin-bottom: 15px;
display: block;
@ -66,6 +71,32 @@ th, td {
padding: 5px;
}
td > h2 {
cursor: pointer;
font-size: 120%;
}
td.collapsed {
font-size: 12px;
width: 12px;
border: 0px;
padding: 0;
cursor: pointer;
background: #fafafa;
}
td.collapsed div {
-moz-transform: rotate(-90.0deg); /* FF3.5+ */
-o-transform: rotate(-90.0deg); /* Opera 10.5 */
-webkit-transform: rotate(-90.0deg); /* Saf3.1+, Chrome */
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083); /* IE6,IE7 */
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083)"; /* IE8 */
margin-top: 10.3em;
margin-left: -10em;
margin-right: -10em;
text-align: right;
}
td.ssa-prog {
width: 600px;
word-wrap: break-word;
@ -131,14 +162,18 @@ dd.ssa-prog {
font-size: 11px;
}
.highlight-yellow { background-color: yellow; }
.highlight-aquamarine { background-color: aquamarine; }
.highlight-coral { background-color: coral; }
.highlight-lightpink { background-color: lightpink; }
.highlight-lightsteelblue { background-color: lightsteelblue; }
.highlight-palegreen { background-color: palegreen; }
.highlight-powderblue { background-color: powderblue; }
.highlight-skyblue { background-color: skyblue; }
.highlight-lightgray { background-color: lightgray; }
.highlight-yellow { background-color: yellow; }
.highlight-lime { background-color: lime; }
.highlight-khaki { background-color: khaki; }
.highlight-aqua { background-color: aqua; }
.highlight-salmon { background-color: salmon; }
.outline-blue { outline: blue solid 2px; }
.outline-red { outline: red solid 2px; }
@ -147,6 +182,10 @@ dd.ssa-prog {
.outline-fuchsia { outline: fuchsia solid 2px; }
.outline-sienna { outline: sienna solid 2px; }
.outline-gold { outline: gold solid 2px; }
.outline-orangered { outline: orangered solid 2px; }
.outline-teal { outline: teal solid 2px; }
.outline-maroon { outline: maroon solid 2px; }
.outline-black { outline: black solid 2px; }
</style>
@ -158,8 +197,13 @@ var highlights = [
"highlight-lightpink",
"highlight-lightsteelblue",
"highlight-palegreen",
"highlight-skyblue",
"highlight-lightgray",
"highlight-yellow"
"highlight-yellow",
"highlight-lime",
"highlight-khaki",
"highlight-aqua",
"highlight-salmon"
];
// state: which value is highlighted this color?
@ -176,7 +220,11 @@ var outlines = [
"outline-darkolivegreen",
"outline-fuchsia",
"outline-sienna",
"outline-gold"
"outline-gold",
"outline-orangered",
"outline-teal",
"outline-maroon",
"outline-black"
];
// state: which value is outlined this color?
@ -263,6 +311,56 @@ window.onload = function() {
for (var i = 0; i < ssablocks.length; i++) {
ssablocks[i].addEventListener('click', ssaBlockClicked);
}
var expandedDefault = [
"start",
"deadcode",
"opt",
"lower",
"late deadcode",
"regalloc",
"genssa",
]
function isExpDefault(id) {
for (var i = 0; i < expandedDefault.length; i++) {
if (id.startsWith(expandedDefault[i])) {
return true;
}
}
return false;
}
function toggler(phase) {
return function() {
toggle_cell(phase+'-col');
toggle_cell(phase+'-exp');
};
}
function toggle_cell(id) {
var e = document.getElementById(id);
if(e.style.display == 'table-cell')
e.style.display = 'none';
else
e.style.display = 'table-cell';
}
var td = document.getElementsByTagName("td");
for (var i = 0; i < td.length; i++) {
var id = td[i].id;
var def = isExpDefault(id);
var phase = id.substr(0, id.length-4);
if (id.endsWith("-exp")) {
var h2 = td[i].getElementsByTagName("h2");
if (h2 && h2[0]) {
h2[0].addEventListener('click', toggler(phase));
}
} else {
td[i].addEventListener('click', toggler(phase));
}
if (id.endsWith("-col") && def || id.endsWith("-exp") && !def) {
td[i].style.display = 'none';
continue
}
td[i].style.display = 'table-cell';
}
};
function toggle_visibility(id) {
@ -316,24 +414,28 @@ func (w *HTMLWriter) Close() {
}
// WriteFunc writes f in a column headed by title.
func (w *HTMLWriter) WriteFunc(title string, f *Func) {
func (w *HTMLWriter) WriteFunc(phase, title string, f *Func) {
if w == nil {
return // avoid generating HTML just to discard it
}
w.WriteColumn(title, "", f.HTML())
w.WriteColumn(phase, title, "", f.HTML())
// TODO: Add visual representation of f's CFG.
}
// WriteColumn writes raw HTML in a column headed by title.
// It is intended for pre- and post-compilation log output.
func (w *HTMLWriter) WriteColumn(title, class, html string) {
func (w *HTMLWriter) WriteColumn(phase, title, class, html string) {
if w == nil {
return
}
id := strings.Replace(phase, " ", "-", -1)
// collapsed column
w.Printf("<td id=\"%v-col\" class=\"collapsed\"><div>%v</div></td>", id, phase)
if class == "" {
w.WriteString("<td>")
w.Printf("<td id=\"%v-exp\">", id)
} else {
w.WriteString("<td class=\"" + class + "\">")
w.Printf("<td id=\"%v-exp\" class=\"%v\">", id, class)
}
w.WriteString("<h2>" + title + "</h2>")
w.WriteString(html)

View file

@ -1,3 +1,7 @@
// Copyright 2018 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.
package ssa
import "fmt"
@ -154,7 +158,7 @@ nextb:
// if the increment is ±1 or when the limits are constants.
if inc.AuxInt != 1 && inc.AuxInt != -1 {
ok := false
if min.Op == OpConst64 && max.Op == OpConst64 {
if min.Op == OpConst64 && max.Op == OpConst64 && inc.AuxInt != 0 {
if max.AuxInt > min.AuxInt && max.AuxInt%inc.AuxInt == min.AuxInt%inc.AuxInt { // handle overflow
ok = true
}

View file

@ -1275,6 +1275,8 @@ const (
OpARM64LoweredAtomicExchange32
OpARM64LoweredAtomicAdd64
OpARM64LoweredAtomicAdd32
OpARM64LoweredAtomicAdd64Variant
OpARM64LoweredAtomicAdd32Variant
OpARM64LoweredAtomicCas64
OpARM64LoweredAtomicCas32
OpARM64LoweredAtomicAnd8
@ -2287,6 +2289,8 @@ const (
OpAtomicCompareAndSwap64
OpAtomicAnd8
OpAtomicOr8
OpAtomicAdd32Variant
OpAtomicAdd64Variant
OpClobber
)
@ -7952,11 +7956,12 @@ var opcodeTable = [...]opInfo{
asm: x86.ACMOVLNE,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 1, // AX
outputs: []outputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
@ -8012,11 +8017,12 @@ var opcodeTable = [...]opInfo{
asm: x86.ACMOVWNE,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 1, // AX
outputs: []outputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{0, 65518}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
@ -16722,6 +16728,38 @@ var opcodeTable = [...]opInfo{
},
},
},
{
name: "LoweredAtomicAdd64Variant",
argLen: 3,
resultNotInArgs: true,
faultOnNilArg0: true,
hasSideEffects: true,
reg: regInfo{
inputs: []inputInfo{
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
},
outputs: []outputInfo{
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
},
},
},
{
name: "LoweredAtomicAdd32Variant",
argLen: 3,
resultNotInArgs: true,
faultOnNilArg0: true,
hasSideEffects: true,
reg: regInfo{
inputs: []inputInfo{
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
},
outputs: []outputInfo{
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
},
},
},
{
name: "LoweredAtomicCas64",
argLen: 4,
@ -16759,29 +16797,37 @@ var opcodeTable = [...]opInfo{
},
},
{
name: "LoweredAtomicAnd8",
argLen: 3,
faultOnNilArg0: true,
hasSideEffects: true,
asm: arm64.AAND,
name: "LoweredAtomicAnd8",
argLen: 3,
resultNotInArgs: true,
faultOnNilArg0: true,
hasSideEffects: true,
asm: arm64.AAND,
reg: regInfo{
inputs: []inputInfo{
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
},
outputs: []outputInfo{
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
},
},
},
{
name: "LoweredAtomicOr8",
argLen: 3,
faultOnNilArg0: true,
hasSideEffects: true,
asm: arm64.AORR,
name: "LoweredAtomicOr8",
argLen: 3,
resultNotInArgs: true,
faultOnNilArg0: true,
hasSideEffects: true,
asm: arm64.AORR,
reg: regInfo{
inputs: []inputInfo{
{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
},
outputs: []outputInfo{
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
},
},
},
{
@ -27817,6 +27863,18 @@ var opcodeTable = [...]opInfo{
hasSideEffects: true,
generic: true,
},
{
name: "AtomicAdd32Variant",
argLen: 3,
hasSideEffects: true,
generic: true,
},
{
name: "AtomicAdd64Variant",
argLen: 3,
hasSideEffects: true,
generic: true,
},
{
name: "Clobber",
auxType: auxSymOff,

View file

@ -4044,7 +4044,7 @@ func rewriteValueARM_OpARMBFX_0(v *Value) bool {
func rewriteValueARM_OpARMBFXU_0(v *Value) bool {
// match: (BFXU [c] (MOVWconst [d]))
// cond:
// result: (MOVWconst [int64(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
// result: (MOVWconst [int64(int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))))])
for {
c := v.AuxInt
v_0 := v.Args[0]
@ -4053,7 +4053,7 @@ func rewriteValueARM_OpARMBFXU_0(v *Value) bool {
}
d := v_0.AuxInt
v.reset(OpARMMOVWconst)
v.AuxInt = int64(uint32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8)))
v.AuxInt = int64(int32(uint32(d) << (32 - uint32(c&0xff) - uint32(c>>8)) >> (32 - uint32(c>>8))))
return true
}
return false
@ -14103,7 +14103,7 @@ func rewriteValueARM_OpARMSLL_0(v *Value) bool {
func rewriteValueARM_OpARMSLLconst_0(v *Value) bool {
// match: (SLLconst [c] (MOVWconst [d]))
// cond:
// result: (MOVWconst [int64(uint32(d)<<uint64(c))])
// result: (MOVWconst [int64(int32(uint32(d)<<uint64(c)))])
for {
c := v.AuxInt
v_0 := v.Args[0]
@ -14112,7 +14112,7 @@ func rewriteValueARM_OpARMSLLconst_0(v *Value) bool {
}
d := v_0.AuxInt
v.reset(OpARMMOVWconst)
v.AuxInt = int64(uint32(d) << uint64(c))
v.AuxInt = int64(int32(uint32(d) << uint64(c)))
return true
}
return false
@ -14274,7 +14274,7 @@ func rewriteValueARM_OpARMSRL_0(v *Value) bool {
func rewriteValueARM_OpARMSRLconst_0(v *Value) bool {
// match: (SRLconst [c] (MOVWconst [d]))
// cond:
// result: (MOVWconst [int64(uint32(d)>>uint64(c))])
// result: (MOVWconst [int64(int32(uint32(d)>>uint64(c)))])
for {
c := v.AuxInt
v_0 := v.Args[0]
@ -14283,7 +14283,7 @@ func rewriteValueARM_OpARMSRLconst_0(v *Value) bool {
}
d := v_0.AuxInt
v.reset(OpARMMOVWconst)
v.AuxInt = int64(uint32(d) >> uint64(c))
v.AuxInt = int64(int32(uint32(d) >> uint64(c)))
return true
}
// match: (SRLconst (SLLconst x [c]) [d])
@ -21295,7 +21295,7 @@ func rewriteValueARM_OpSelect0_0(v *Value) bool {
}
// match: (Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
// cond:
// result: (MOVWconst [int64(uint32(c)/uint32(d))])
// result: (MOVWconst [int64(int32(uint32(c)/uint32(d)))])
for {
v_0 := v.Args[0]
if v_0.Op != OpARMCALLudiv {
@ -21313,7 +21313,7 @@ func rewriteValueARM_OpSelect0_0(v *Value) bool {
}
d := v_0_1.AuxInt
v.reset(OpARMMOVWconst)
v.AuxInt = int64(uint32(c) / uint32(d))
v.AuxInt = int64(int32(uint32(c) / uint32(d)))
return true
}
return false
@ -21364,7 +21364,7 @@ func rewriteValueARM_OpSelect1_0(v *Value) bool {
}
// match: (Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d])))
// cond:
// result: (MOVWconst [int64(uint32(c)%uint32(d))])
// result: (MOVWconst [int64(int32(uint32(c)%uint32(d)))])
for {
v_0 := v.Args[0]
if v_0.Op != OpARMCALLudiv {
@ -21382,7 +21382,7 @@ func rewriteValueARM_OpSelect1_0(v *Value) bool {
}
d := v_0_1.AuxInt
v.reset(OpARMMOVWconst)
v.AuxInt = int64(uint32(c) % uint32(d))
v.AuxInt = int64(int32(uint32(c) % uint32(d)))
return true
}
return false

View file

@ -341,8 +341,12 @@ func rewriteValueARM64(v *Value) bool {
return rewriteValueARM64_OpAndB_0(v)
case OpAtomicAdd32:
return rewriteValueARM64_OpAtomicAdd32_0(v)
case OpAtomicAdd32Variant:
return rewriteValueARM64_OpAtomicAdd32Variant_0(v)
case OpAtomicAdd64:
return rewriteValueARM64_OpAtomicAdd64_0(v)
case OpAtomicAdd64Variant:
return rewriteValueARM64_OpAtomicAdd64Variant_0(v)
case OpAtomicAnd8:
return rewriteValueARM64_OpAtomicAnd8_0(v)
case OpAtomicCompareAndSwap32:
@ -25908,6 +25912,22 @@ func rewriteValueARM64_OpAtomicAdd32_0(v *Value) bool {
return true
}
}
func rewriteValueARM64_OpAtomicAdd32Variant_0(v *Value) bool {
// match: (AtomicAdd32Variant ptr val mem)
// cond:
// result: (LoweredAtomicAdd32Variant ptr val mem)
for {
_ = v.Args[2]
ptr := v.Args[0]
val := v.Args[1]
mem := v.Args[2]
v.reset(OpARM64LoweredAtomicAdd32Variant)
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
return true
}
}
func rewriteValueARM64_OpAtomicAdd64_0(v *Value) bool {
// match: (AtomicAdd64 ptr val mem)
// cond:
@ -25924,22 +25944,44 @@ func rewriteValueARM64_OpAtomicAdd64_0(v *Value) bool {
return true
}
}
func rewriteValueARM64_OpAtomicAnd8_0(v *Value) bool {
// match: (AtomicAnd8 ptr val mem)
func rewriteValueARM64_OpAtomicAdd64Variant_0(v *Value) bool {
// match: (AtomicAdd64Variant ptr val mem)
// cond:
// result: (LoweredAtomicAnd8 ptr val mem)
// result: (LoweredAtomicAdd64Variant ptr val mem)
for {
_ = v.Args[2]
ptr := v.Args[0]
val := v.Args[1]
mem := v.Args[2]
v.reset(OpARM64LoweredAtomicAnd8)
v.reset(OpARM64LoweredAtomicAdd64Variant)
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
return true
}
}
func rewriteValueARM64_OpAtomicAnd8_0(v *Value) bool {
b := v.Block
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (AtomicAnd8 ptr val mem)
// cond:
// result: (Select1 (LoweredAtomicAnd8 ptr val mem))
for {
_ = v.Args[2]
ptr := v.Args[0]
val := v.Args[1]
mem := v.Args[2]
v.reset(OpSelect1)
v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicAnd8, types.NewTuple(typ.UInt8, types.TypeMem))
v0.AddArg(ptr)
v0.AddArg(val)
v0.AddArg(mem)
v.AddArg(v0)
return true
}
}
func rewriteValueARM64_OpAtomicCompareAndSwap32_0(v *Value) bool {
// match: (AtomicCompareAndSwap32 ptr old new_ mem)
// cond:
@ -26051,18 +26093,24 @@ func rewriteValueARM64_OpAtomicLoadPtr_0(v *Value) bool {
}
}
func rewriteValueARM64_OpAtomicOr8_0(v *Value) bool {
b := v.Block
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (AtomicOr8 ptr val mem)
// cond:
// result: (LoweredAtomicOr8 ptr val mem)
// result: (Select1 (LoweredAtomicOr8 ptr val mem))
for {
_ = v.Args[2]
ptr := v.Args[0]
val := v.Args[1]
mem := v.Args[2]
v.reset(OpARM64LoweredAtomicOr8)
v.AddArg(ptr)
v.AddArg(val)
v.AddArg(mem)
v.reset(OpSelect1)
v0 := b.NewValue0(v.Pos, OpARM64LoweredAtomicOr8, types.NewTuple(typ.UInt8, types.TypeMem))
v0.AddArg(ptr)
v0.AddArg(val)
v0.AddArg(mem)
v.AddArg(v0)
return true
}
}

View file

@ -5210,6 +5210,27 @@ func rewriteValueWasm_OpWasmI64AddConst_0(v *Value) bool {
v.AddArg(x)
return true
}
// match: (I64AddConst [off] (LoweredAddr {sym} [off2] base))
// cond: isU32Bit(off+off2)
// result: (LoweredAddr {sym} [off+off2] base)
for {
off := v.AuxInt
v_0 := v.Args[0]
if v_0.Op != OpWasmLoweredAddr {
break
}
off2 := v_0.AuxInt
sym := v_0.Aux
base := v_0.Args[0]
if !(isU32Bit(off + off2)) {
break
}
v.reset(OpWasmLoweredAddr)
v.AuxInt = off + off2
v.Aux = sym
v.AddArg(base)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64And_0(v *Value) bool {

View file

@ -310,6 +310,7 @@ func storeOrder(values []*Value, sset *sparseSet, storeNumber []int32) []*Value
// A constant bound allows this to be stack-allocated. 64 is
// enough to cover almost every storeOrder call.
stores := make([]*Value, 0, 64)
var vardefs map[interface{}]*Value // OpAddr must depend on Vardef for Node
hasNilCheck := false
sset.clear() // sset is the set of stores that are used in other values
for _, v := range values {
@ -323,6 +324,12 @@ func storeOrder(values []*Value, sset *sparseSet, storeNumber []int32) []*Value
if v.Op == OpNilCheck {
hasNilCheck = true
}
if v.Op == OpVarDef {
if vardefs == nil { // Lazy init, not all blocks have vardefs
vardefs = make(map[interface{}]*Value)
}
vardefs[v.Aux] = v
}
}
if len(stores) == 0 || !hasNilCheck && f.pass.name == "nilcheckelim" {
// there is no store, the order does not matter
@ -386,7 +393,20 @@ func storeOrder(values []*Value, sset *sparseSet, storeNumber []int32) []*Value
stack = stack[:len(stack)-1]
continue
}
if w.Op == OpAddr {
// OpAddr depends only on relevant VarDef
vn := int32(0)
if vardefs != nil {
if a := vardefs[w.Aux]; a != nil { // if nil, it is in some other block, or global or arg
vn = storeNumber[a.ID]
}
}
vn += 2
storeNumber[w.ID] = vn
count[vn]++
stack = stack[:len(stack)-1]
continue
}
max := int32(0) // latest store dependency
argsdone := true
for _, a := range w.Args {

View file

@ -80,15 +80,24 @@ func IsDclstackValid() bool {
// PkgDef returns the definition associated with s at package scope.
func (s *Sym) PkgDef() *Node {
return *s.pkgDefPtr()
}
// SetPkgDef sets the definition associated with s at package scope.
func (s *Sym) SetPkgDef(n *Node) {
*s.pkgDefPtr() = n
}
func (s *Sym) pkgDefPtr() **Node {
// Look for outermost saved declaration, which must be the
// package scope definition, if present.
for _, d := range dclstack {
if s == d.sym {
return d.def
return &d.def
}
}
// Otherwise, the declaration hasn't been shadowed within a
// function scope.
return s.Def
return &s.Def
}

View file

@ -232,19 +232,13 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value) {
case ssa.OpWasmLoweredAddr:
p := s.Prog(wasm.AGet)
switch n := v.Aux.(type) {
p.From.Type = obj.TYPE_ADDR
switch v.Aux.(type) {
case *obj.LSym:
p.From = obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_EXTERN, Sym: n}
gc.AddAux(&p.From, v)
case *gc.Node:
p.From = obj.Addr{
Type: obj.TYPE_ADDR,
Name: obj.NAME_AUTO,
Reg: v.Args[0].Reg(),
Offset: n.Xoffset,
}
if n.Class() == gc.PPARAM || n.Class() == gc.PPARAMOUT {
p.From.Name = obj.NAME_PARAM
}
p.From.Reg = v.Args[0].Reg()
gc.AddAux(&p.From, v)
default:
panic("wasm: bad LoweredAddr")
}

View file

@ -18,7 +18,6 @@ import (
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"testing"
)
@ -267,9 +266,6 @@ func TestCoverFunc(t *testing.T) {
// Check that cover produces correct HTML.
// Issue #25767.
func TestCoverHTML(t *testing.T) {
if _, err := exec.LookPath("diff"); err != nil {
t.Skipf("skip test on %s: diff command is required", runtime.GOOS)
}
testenv.MustHaveGoBuild(t)
if !*debug {
defer os.Remove(testcover)
@ -307,16 +303,30 @@ func TestCoverHTML(t *testing.T) {
in = false
}
}
if err := ioutil.WriteFile(htmlHTML, out.Bytes(), 0644); err != nil {
t.Fatal(err)
golden, err := ioutil.ReadFile(htmlGolden)
if err != nil {
t.Fatalf("reading golden file: %v", err)
}
diff := "diff"
if runtime.GOOS == "plan9" {
diff = "/bin/ape/diff"
// Ignore white space differences.
// Break into lines, then compare by breaking into words.
goldenLines := strings.Split(string(golden), "\n")
outLines := strings.Split(out.String(), "\n")
// Compare at the line level, stopping at first different line so
// we don't generate tons of output if there's an inserted or deleted line.
for i, goldenLine := range goldenLines {
if i > len(outLines) {
t.Fatalf("output shorter than golden; stops before line %d: %s\n", i+1, goldenLine)
}
// Convert all white space to simple spaces, for easy comparison.
goldenLine = strings.Join(strings.Fields(goldenLine), " ")
outLine := strings.Join(strings.Fields(outLines[i]), " ")
if outLine != goldenLine {
t.Fatalf("line %d differs: got:\n\t%s\nwant:\n\t%s", i+1, outLine, goldenLine)
}
}
if len(goldenLines) != len(outLines) {
t.Fatalf("output longer than golden; first extra output line %d: %q\n", len(goldenLines)+1, outLines[len(goldenLines)])
}
// diff -uw testdata/html/html.html testdata/html/html.golden
cmd = exec.Command(diff, "-u", "-w", htmlHTML, htmlGolden)
run(cmd, t)
}
func run(c *exec.Cmd, t *testing.T) {

View file

@ -67,6 +67,7 @@ var okgoarch = []string{
"mips64le",
"ppc64",
"ppc64le",
"riscv64",
"s390x",
"wasm",
}
@ -1393,6 +1394,7 @@ var cgoEnabled = map[string]bool{
"linux/mipsle": true,
"linux/mips64": true,
"linux/mips64le": true,
"linux/riscv64": true,
"linux/s390x": true,
"android/386": true,
"android/amd64": true,

View file

@ -80,6 +80,8 @@ var bootstrapDirs = []string{
"cmd/link/internal/s390x",
"cmd/link/internal/sym",
"cmd/link/internal/x86",
"compress/flate",
"compress/zlib",
"cmd/link/internal/wasm",
"container/heap",
"debug/dwarf",

43
src/cmd/dist/test.go vendored
View file

@ -308,11 +308,10 @@ func (t *tester) registerStdTest(pkg string) {
timeoutSec := 180
for _, pkg := range stdMatches {
if pkg == "cmd/go" {
timeoutSec *= 2
timeoutSec *= 3
break
}
}
args := []string{
"test",
short(),
@ -325,6 +324,8 @@ func (t *tester) registerStdTest(pkg string) {
}
if t.compileOnly {
args = append(args, "-run=^$")
} else if goos == "js" && goarch == "wasm" {
args = append(args, "-run=^Test") // exclude examples; Issue 25913
}
args = append(args, stdMatches...)
cmd := exec.Command("go", args...)
@ -355,7 +356,8 @@ func (t *tester) registerRaceBenchTest(pkg string) {
"test",
short(),
"-race",
"-run=^$", // nothing. only benchmarks.
t.timeout(1200), // longer timeout for race with benchmarks
"-run=^$", // nothing. only benchmarks.
"-benchtime=.1s",
"-cpu=4",
}
@ -449,7 +451,7 @@ func (t *tester) registerTests() {
}
// Runtime CPU tests.
if !t.compileOnly {
if !t.compileOnly && goos != "js" { // js can't handle -cpu != 1
testName := "runtime:cpu124"
t.tests = append(t.tests, distTest{
name: testName,
@ -490,9 +492,9 @@ func (t *tester) registerTests() {
// On the builders only, test that a moved GOROOT still works.
// Fails on iOS because CC_FOR_TARGET refers to clangwrap.sh
// in the unmoved GOROOT.
// Fails on Android with an exec format error.
// Fails on Android and js/wasm with an exec format error.
// Fails on plan9 with "cannot find GOROOT" (issue #21016).
if os.Getenv("GO_BUILDER_NAME") != "" && goos != "android" && !t.iOS() && goos != "plan9" {
if os.Getenv("GO_BUILDER_NAME") != "" && goos != "android" && !t.iOS() && goos != "plan9" && goos != "js" {
t.tests = append(t.tests, distTest{
name: "moved_goroot",
heading: "moved GOROOT",
@ -583,14 +585,16 @@ func (t *tester) registerTests() {
}
// sync tests
t.tests = append(t.tests, distTest{
name: "sync_cpu",
heading: "sync -cpu=10",
fn: func(dt *distTest) error {
t.addCmd(dt, "src", t.goTest(), "sync", t.timeout(120), "-cpu=10", t.runFlag(""))
return nil
},
})
if goos != "js" { // js doesn't support -cpu=10
t.tests = append(t.tests, distTest{
name: "sync_cpu",
heading: "sync -cpu=10",
fn: func(dt *distTest) error {
t.addCmd(dt, "src", t.goTest(), "sync", t.timeout(120), "-cpu=10", t.runFlag(""))
return nil
},
})
}
if t.raceDetectorSupported() {
t.tests = append(t.tests, distTest{
@ -714,7 +718,7 @@ func (t *tester) registerTests() {
// Doc tests only run on builders.
// They find problems approximately never.
if t.hasBash() && goos != "nacl" && goos != "android" && !t.iOS() && os.Getenv("GO_BUILDER_NAME") != "" {
if t.hasBash() && goos != "nacl" && goos != "js" && goos != "android" && !t.iOS() && os.Getenv("GO_BUILDER_NAME") != "" {
t.registerTest("doc_progs", "../doc/progs", "time", "go", "run", "run.go")
t.registerTest("wiki", "../doc/articles/wiki", "./test.bash")
t.registerTest("codewalk", "../doc/codewalk", "time", "./run")
@ -740,7 +744,7 @@ func (t *tester) registerTests() {
})
}
}
if goos != "nacl" && goos != "android" && !t.iOS() {
if goos != "nacl" && goos != "android" && !t.iOS() && goos != "js" {
t.tests = append(t.tests, distTest{
name: "api",
heading: "API check",
@ -1318,7 +1322,7 @@ func (t *tester) raceDetectorSupported() bool {
case "linux", "darwin", "freebsd", "windows":
// The race detector doesn't work on Alpine Linux:
// golang.org/issue/14481
return t.cgoEnabled && goarch == "amd64" && gohostos == goos && !isAlpineLinux()
return t.cgoEnabled && (goarch == "amd64" || goarch == "ppc64le") && gohostos == goos && !isAlpineLinux()
}
return false
}
@ -1335,13 +1339,16 @@ func (t *tester) runFlag(rx string) string {
if t.compileOnly {
return "-run=^$"
}
if rx == "" && goos == "js" && goarch == "wasm" {
return "-run=^Test" // exclude examples; Issue 25913
}
return "-run=" + rx
}
func (t *tester) raceTest(dt *distTest) error {
t.addCmd(dt, "src", t.goTest(), "-race", "-i", "runtime/race", "flag", "os", "os/exec")
t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("Output"), "runtime/race")
t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace|TestTypeRace"), "flag", "os", "os/exec", "encoding/gob")
t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace|TestTypeRace|TestFdRace|TestFileCloseRace"), "flag", "net", "os", "os/exec", "encoding/gob")
// We don't want the following line, because it
// slows down all.bash (by 10 seconds on my laptop).
// The race builder should catch any error here, but doesn't.

View file

@ -26,7 +26,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(err)
}
dirsInit(testdataDir)
dirsInit(testdataDir, filepath.Join(testdataDir, "nested"), filepath.Join(testdataDir, "nested", "nested"))
os.Exit(m.Run())
}
@ -510,6 +510,24 @@ var tests = []test{
"\\)\n+const", // This will appear if the const decl appears twice.
},
},
{
"non-imported: pkg.sym",
[]string{"nested.Foo"},
[]string{"Foo struct"},
nil,
},
{
"non-imported: pkg only",
[]string{"nested"},
[]string{"Foo struct"},
nil,
},
{
"non-imported: pkg sym",
[]string{"nested", "Foo"},
[]string{"Foo struct"},
nil,
},
}
func TestDoc(t *testing.T) {

View file

@ -189,11 +189,16 @@ func parseArgs(args []string) (pkg *build.Package, path, symbol string, more boo
// Done below.
case 2:
// Package must be findable and importable.
packagePath, ok := findPackage(arg)
if !ok {
return nil, args[0], args[1], false
for {
packagePath, ok := findNextPackage(arg)
if !ok {
break
}
if pkg, err := build.ImportDir(packagePath, build.ImportComment); err == nil {
return pkg, arg, args[1], true
}
}
return importDir(packagePath), arg, args[1], true
return nil, args[0], args[1], false
}
// Usual case: one argument.
// If it contains slashes, it begins with a package path.
@ -241,9 +246,15 @@ func parseArgs(args []string) (pkg *build.Package, path, symbol string, more boo
}
// See if we have the basename or tail of a package, as in json for encoding/json
// or ivy/value for robpike.io/ivy/value.
path, ok := findPackage(arg[0:period])
if ok {
return importDir(path), arg[0:period], symbol, true
pkgName := arg[:period]
for {
path, ok := findNextPackage(pkgName)
if !ok {
break
}
if pkg, err = build.ImportDir(path, build.ImportComment); err == nil {
return pkg, arg[0:period], symbol, true
}
}
dirs.Reset() // Next iteration of for loop must scan all the directories again.
}
@ -338,9 +349,9 @@ func isUpper(name string) bool {
return unicode.IsUpper(ch)
}
// findPackage returns the full file name path that first matches the
// findNextPackage returns the next full file name path that matches the
// (perhaps partial) package path pkg. The boolean reports if any match was found.
func findPackage(pkg string) (string, bool) {
func findNextPackage(pkg string) (string, bool) {
if pkg == "" || isUpper(pkg) { // Upper case symbol cannot be a package name.
return "", false
}

4
src/cmd/doc/testdata/nested/ignore.go vendored Normal file
View file

@ -0,0 +1,4 @@
// +build ignore
// Ignored package
package nested

View file

@ -0,0 +1,4 @@
package nested
type Foo struct {
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// DO NOT EDIT THIS FILE. GENERATED BY mkalldocs.sh.
// Code generated by mkalldocs.sh; DO NOT EDIT.
// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.
// Go is a tool for managing Go source code.
@ -419,6 +419,12 @@
// (gofmt), a fully qualified path (/usr/you/bin/mytool), or a
// command alias, described below.
//
// To convey to humans and machine tools that code is generated,
// generated source should have a line early in the file that
// matches the following regular expression (in Go syntax):
//
// ^// Code generated .* DO NOT EDIT\.$
//
// Note that go generate does not parse the file, so lines that look
// like directives in comments or multiline strings will be treated
// as directives.
@ -579,7 +585,7 @@
//
// Usage:
//
// go list [-cgo] [-deps] [-e] [-export] [-f format] [-json] [-list] [-test] [build flags] [packages]
// go list [-cgo] [-deps] [-e] [-export] [-f format] [-json] [-test] [build flags] [packages]
//
// List lists the packages named by the import paths, one per line.
//
@ -1006,6 +1012,7 @@
// in the standard user cache directory for the current operating system.
// Setting the GOCACHE environment variable overrides this default,
// and running 'go env GOCACHE' prints the current cache directory.
// You can set the variable to 'off' to disable the cache.
//
// The go command periodically deletes cached data that has not been
// used recently. Running 'go clean -cache' deletes all cached data.

View file

@ -99,6 +99,7 @@ func init() {
var testGOROOT string
var testCC string
var testGOCACHE string
// The TestMain function creates a go command for testing purposes and
// deletes it after the tests have been run.
@ -175,6 +176,13 @@ func TestMain(m *testing.M) {
}
}
out, err = exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
os.Exit(2)
}
testGOCACHE = strings.TrimSpace(string(out))
// As of Sept 2017, MSan is only supported on linux/amd64.
// https://github.com/google/sanitizers/wiki/MemorySanitizer#getting-memorysanitizer
canMSan = canCgo && runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
@ -198,7 +206,7 @@ func TestMain(m *testing.M) {
}
os.Setenv("HOME", "/test-go-home-does-not-exist")
if os.Getenv("GOCACHE") == "" {
os.Setenv("GOCACHE", "off") // because $HOME is gone
os.Setenv("GOCACHE", testGOCACHE) // because $HOME is gone
}
r := m.Run()
@ -791,7 +799,6 @@ func TestBuildComplex(t *testing.T) {
tg.run("build", "-x", "-o", os.DevNull, "complex")
if _, err := exec.LookPath("gccgo"); err == nil {
t.Skip("golang.org/issue/22472")
tg.run("build", "-x", "-o", os.DevNull, "-compiler=gccgo", "complex")
}
}
@ -1253,14 +1260,14 @@ func TestInternalPackagesInGOROOTAreRespected(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.runFail("build", "-v", "./testdata/testinternal")
tg.grepBoth(`testinternal(\/|\\)p\.go\:3\:8\: use of internal package not allowed`, "wrong error message for testdata/testinternal")
tg.grepBoth(`testinternal(\/|\\)p\.go\:3\:8\: use of internal package net/http/internal not allowed`, "wrong error message for testdata/testinternal")
}
func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.runFail("build", "-v", "./testdata/testinternal2")
tg.grepBoth(`testinternal2(\/|\\)p\.go\:3\:8\: use of internal package not allowed`, "wrote error message for testdata/testinternal2")
tg.grepBoth(`testinternal2(\/|\\)p\.go\:3\:8\: use of internal package .*internal/w not allowed`, "wrote error message for testdata/testinternal2")
}
func TestRunInternal(t *testing.T) {
@ -1270,7 +1277,7 @@ func TestRunInternal(t *testing.T) {
tg.setenv("GOPATH", dir)
tg.run("run", filepath.Join(dir, "src/run/good.go"))
tg.runFail("run", filepath.Join(dir, "src/run/bad.go"))
tg.grepStderr(`testdata(\/|\\)src(\/|\\)run(\/|\\)bad\.go\:3\:8\: use of internal package not allowed`, "unexpected error for run/bad.go")
tg.grepStderr(`testdata(\/|\\)src(\/|\\)run(\/|\\)bad\.go\:3\:8\: use of internal package run/subdir/internal/private not allowed`, "unexpected error for run/bad.go")
}
func TestRunPkg(t *testing.T) {
@ -1975,6 +1982,10 @@ func TestGoListTest(t *testing.T) {
tg.run("list", "-test", "runtime/cgo")
tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
tg.grepStdout(`^reflect$`, "missing reflect")
tg.grepStdoutNot(`^sort`, "unexpected sort")
}
func TestGoListCgo(t *testing.T) {
@ -3072,7 +3083,6 @@ func TestIssue7573(t *testing.T) {
if _, err := exec.LookPath("gccgo"); err != nil {
t.Skip("skipping because no gccgo compiler found")
}
t.Skip("golang.org/issue/22472")
tg := testgo(t)
defer tg.cleanup()
@ -3257,9 +3267,9 @@ func TestGoTestCoverMultiPackage(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.run("test", "-cover", "./testdata/testcover/...")
tg.grepStdout(`\?.*testdata/testcover/pkg1.*\d\.\d\d\ds.*coverage:.*0\.0% of statements \[no test files\]`, "expected [no test files] for pkg1")
tg.grepStdout(`ok.*testdata/testcover/pkg2.*\d\.\d\d\ds.*coverage:.*0\.0% of statements \[no tests to run\]`, "expected [no tests to run] for pkg2")
tg.grepStdout(`ok.*testdata/testcover/pkg3.*\d\.\d\d\ds.*coverage:.*100\.0% of statements`, "expected 100% coverage for pkg3")
tg.grepStdout(`\?.*testdata/testcover/pkg1.*(\d\.\d\d\ds|cached).*coverage:.*0\.0% of statements \[no test files\]`, "expected [no test files] for pkg1")
tg.grepStdout(`ok.*testdata/testcover/pkg2.*(\d\.\d\d\ds|cached).*coverage:.*0\.0% of statements \[no tests to run\]`, "expected [no tests to run] for pkg2")
tg.grepStdout(`ok.*testdata/testcover/pkg3.*(\d\.\d\d\ds|cached).*coverage:.*100\.0% of statements`, "expected 100% coverage for pkg3")
}
// issue 24570
@ -3268,9 +3278,9 @@ func TestGoTestCoverprofileMultiPackage(t *testing.T) {
defer tg.cleanup()
tg.creatingTemp("testdata/cover.out")
tg.run("test", "-coverprofile=testdata/cover.out", "./testdata/testcover/...")
tg.grepStdout(`\?.*testdata/testcover/pkg1.*\d\.\d\d\ds.*coverage:.*0\.0% of statements \[no test files\]`, "expected [no test files] for pkg1")
tg.grepStdout(`ok.*testdata/testcover/pkg2.*\d\.\d\d\ds.*coverage:.*0\.0% of statements \[no tests to run\]`, "expected [no tests to run] for pkg2")
tg.grepStdout(`ok.*testdata/testcover/pkg3.*\d\.\d\d\ds.*coverage:.*100\.0% of statements`, "expected 100% coverage for pkg3")
tg.grepStdout(`\?.*testdata/testcover/pkg1.*(\d\.\d\d\ds|cached).*coverage:.*0\.0% of statements \[no test files\]`, "expected [no test files] for pkg1")
tg.grepStdout(`ok.*testdata/testcover/pkg2.*(\d\.\d\d\ds|cached).*coverage:.*0\.0% of statements \[no tests to run\]`, "expected [no tests to run] for pkg2")
tg.grepStdout(`ok.*testdata/testcover/pkg3.*(\d\.\d\d\ds|cached).*coverage:.*100\.0% of statements`, "expected 100% coverage for pkg3")
if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
t.Error(err)
} else {
@ -5815,6 +5825,11 @@ func TestTestVet(t *testing.T) {
tg.runFail("test", "vetfail/...")
tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
tg.grepStdout(`ok\s+vetfail/p2`, "did not run vetfail/p2")
// Use -a so that we need to recompute the vet-specific export data for
// vetfail/p1.
tg.run("test", "-a", "vetfail/p2")
tg.grepStderrNot(`invalid.*constraint`, "did diagnose bad build constraint in vetxonly mode")
}
func TestTestVetRebuild(t *testing.T) {

View file

@ -189,6 +189,21 @@ func (c *Cache) get(id ActionID) (Entry, error) {
return Entry{buf, size, time.Unix(0, tm)}, nil
}
// GetFile looks up the action ID in the cache and returns
// the name of the corresponding data file.
func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) {
entry, err = c.Get(id)
if err != nil {
return "", Entry{}, err
}
file = c.OutputFile(entry.OutputID)
info, err := os.Stat(file)
if err != nil || info.Size() != entry.Size {
return "", Entry{}, errMissing
}
return file, entry, nil
}
// GetBytes looks up the action ID in the cache and returns
// the corresponding output bytes.
// GetBytes should only be used for data that can be expected to fit in memory.

View file

@ -103,6 +103,16 @@ func init() {
}
}
// There is a copy of findGOROOT, isSameDir, and isGOROOT in
// x/tools/cmd/godoc/goroot.go.
// Try to keep them in sync for now.
// findGOROOT returns the GOROOT value, using either an explicitly
// provided environment variable, a GOROOT that contains the current
// os.Executable value, or else the GOROOT that the binary was built
// with from runtime.GOROOT().
//
// There is a copy of this code in x/tools/cmd/godoc/goroot.go.
func findGOROOT() string {
if env := os.Getenv("GOROOT"); env != "" {
return filepath.Clean(env)
@ -162,6 +172,8 @@ func isSameDir(dir1, dir2 string) bool {
// It does this by looking for the path/pkg/tool directory,
// which is necessary for useful operation of the cmd/go tool,
// and is not typically present in a GOPATH.
//
// There is a copy of this code in x/tools/cmd/godoc/goroot.go.
func isGOROOT(path string) bool {
stat, err := os.Stat(filepath.Join(path, "pkg", "tool"))
if err != nil {

View file

@ -0,0 +1,103 @@
// Copyright 2018 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.
// Package dirhash defines hashes over directory trees.
package dirhash
import (
"archive/zip"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"sort"
"strings"
)
var DefaultHash = Hash1
type Hash func(files []string, open func(string) (io.ReadCloser, error)) (string, error)
func Hash1(files []string, open func(string) (io.ReadCloser, error)) (string, error) {
h := sha256.New()
files = append([]string(nil), files...)
sort.Strings(files)
for _, file := range files {
if strings.Contains(file, "\n") {
return "", errors.New("filenames with newlines are not supported")
}
r, err := open(file)
if err != nil {
return "", err
}
hf := sha256.New()
_, err = io.Copy(hf, r)
r.Close()
if err != nil {
return "", err
}
fmt.Fprintf(h, "%x %s\n", hf.Sum(nil), file)
}
return "h1:" + base64.StdEncoding.EncodeToString(h.Sum(nil)), nil
}
func HashDir(dir, prefix string, hash Hash) (string, error) {
files, err := DirFiles(dir, prefix)
if err != nil {
return "", err
}
osOpen := func(name string) (io.ReadCloser, error) {
return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix)))
}
return hash(files, osOpen)
}
func DirFiles(dir, prefix string) ([]string, error) {
var files []string
dir = filepath.Clean(dir)
err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
rel := file
if dir != "." {
rel = file[len(dir)+1:]
}
f := filepath.Join(prefix, rel)
files = append(files, filepath.ToSlash(f))
return nil
})
if err != nil {
return nil, err
}
return files, nil
}
func HashZip(zipfile string, hash Hash) (string, error) {
z, err := zip.OpenReader(zipfile)
if err != nil {
return "", err
}
defer z.Close()
var files []string
zfiles := make(map[string]*zip.File)
for _, file := range z.File {
files = append(files, file.Name)
zfiles[file.Name] = file
}
zipOpen := func(name string) (io.ReadCloser, error) {
f := zfiles[name]
if f == nil {
return nil, fmt.Errorf("file %q not found in zip", name) // should never happen
}
return f.Open()
}
return hash(files, zipOpen)
}

View file

@ -0,0 +1,135 @@
// Copyright 2018 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.
package dirhash
import (
"archive/zip"
"crypto/sha256"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)
func h(s string) string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))
}
func htop(k string, s string) string {
sum := sha256.Sum256([]byte(s))
return k + ":" + base64.StdEncoding.EncodeToString(sum[:])
}
func TestHash1(t *testing.T) {
files := []string{"xyz", "abc"}
open := func(name string) (io.ReadCloser, error) {
return ioutil.NopCloser(strings.NewReader("data for " + name)), nil
}
want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "abc", h("data for xyz"), "xyz"))
out, err := Hash1(files, open)
if err != nil {
t.Fatal(err)
}
if out != want {
t.Errorf("Hash1(...) = %s, want %s", out, want)
}
_, err = Hash1([]string{"xyz", "a\nbc"}, open)
if err == nil {
t.Error("Hash1: expected error on newline in filenames")
}
}
func TestHashDir(t *testing.T) {
dir, err := ioutil.TempDir("", "dirhash-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil {
t.Fatal(err)
}
want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz"))
out, err := HashDir(dir, "prefix", Hash1)
if err != nil {
t.Fatalf("HashDir: %v", err)
}
if out != want {
t.Errorf("HashDir(...) = %s, want %s", out, want)
}
}
func TestHashZip(t *testing.T) {
f, err := ioutil.TempFile("", "dirhash-test-")
if err != nil {
t.Fatal(err)
}
defer os.Remove(f.Name())
defer f.Close()
z := zip.NewWriter(f)
w, err := z.Create("prefix/xyz")
if err != nil {
t.Fatal(err)
}
w.Write([]byte("data for xyz"))
w, err = z.Create("prefix/abc")
if err != nil {
t.Fatal(err)
}
w.Write([]byte("data for abc"))
if err := z.Close(); err != nil {
t.Fatal(err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz"))
out, err := HashZip(f.Name(), Hash1)
if err != nil {
t.Fatalf("HashDir: %v", err)
}
if out != want {
t.Errorf("HashDir(...) = %s, want %s", out, want)
}
}
func TestDirFiles(t *testing.T) {
dir, err := ioutil.TempDir("", "dirfiles-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil {
t.Fatal(err)
}
if err := os.Mkdir(filepath.Join(dir, "subdir"), 0777); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(dir, "subdir", "xyz"), []byte("data for subdir xyz"), 0666); err != nil {
t.Fatal(err)
}
prefix := "foo/bar@v2.3.4"
out, err := DirFiles(dir, prefix)
if err != nil {
t.Fatalf("DirFiles: %v", err)
}
for _, file := range out {
if !strings.HasPrefix(file, prefix) {
t.Errorf("Dir file = %s, want prefix %s", file, prefix)
}
}
}

Some files were not shown because too many files have changed in this diff Show more