Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
42f20102
Commit
42f20102
authored
Jan 27, 2017
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libgo: update to go1.8rc3
Reviewed-on:
https://go-review.googlesource.com/35844
From-SVN: r244981
parent
3f54004b
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
389 additions
and
92 deletions
+389
-92
libgo/MERGE
+1
-1
libgo/VERSION
+1
-1
libgo/go/cmd/go/go_test.go
+23
-0
libgo/go/cmd/go/pkg.go
+1
-1
libgo/go/database/sql/sql.go
+64
-27
libgo/go/database/sql/sql_test.go
+99
-24
libgo/go/go/printer/nodes.go
+12
-5
libgo/go/go/printer/printer.go
+8
-3
libgo/go/go/printer/testdata/comments2.golden
+59
-0
libgo/go/go/printer/testdata/comments2.input
+63
-0
libgo/go/net/http/client.go
+13
-8
libgo/go/net/http/client_test.go
+41
-20
libgo/go/net/http/serve_test.go
+1
-1
libgo/merge.sh
+3
-1
No files found.
libgo/MERGE
View file @
42f20102
59f181b6fda68ece22882945853ca2df9dbf1c88
2a5f65a98ca483aad2dd74dc2636a7baecc59cf2
The first line of this file holds the git revision number of the
last merge done from the master library sources.
libgo/VERSION
View file @
42f20102
go1.8rc
2
go1.8rc
3
libgo/go/cmd/go/go_test.go
View file @
42f20102
...
...
@@ -3787,3 +3787,26 @@ GLOBL ·constants<>(SB),8,$8
tg
.
setenv
(
"GOPATH"
,
tg
.
path
(
"go"
))
tg
.
run
(
"build"
,
"p"
)
}
// Issue 18778.
func
TestDotDotDotOutsideGOPATH
(
t
*
testing
.
T
)
{
tg
:=
testgo
(
t
)
defer
tg
.
cleanup
()
tg
.
tempFile
(
"pkgs/a.go"
,
`package x`
)
tg
.
tempFile
(
"pkgs/a_test.go"
,
`package x_test
import "testing"
func TestX(t *testing.T) {}`
)
tg
.
tempFile
(
"pkgs/a/a.go"
,
`package a`
)
tg
.
tempFile
(
"pkgs/a/a_test.go"
,
`package a_test
import "testing"
func TestA(t *testing.T) {}`
)
tg
.
cd
(
tg
.
path
(
"pkgs"
))
tg
.
run
(
"build"
,
"./..."
)
tg
.
run
(
"test"
,
"./..."
)
tg
.
run
(
"list"
,
"./..."
)
tg
.
grepStdout
(
"pkgs$"
,
"expected package not listed"
)
tg
.
grepStdout
(
"pkgs/a"
,
"expected package not listed"
)
}
libgo/go/cmd/go/pkg.go
View file @
42f20102
...
...
@@ -433,7 +433,7 @@ func setErrorPos(p *Package, importPos []token.Position) *Package {
func
cleanImport
(
path
string
)
string
{
orig
:=
path
path
=
pathpkg
.
Clean
(
path
)
if
strings
.
HasPrefix
(
orig
,
"./"
)
&&
path
!=
".."
&&
path
!=
"."
&&
!
strings
.
HasPrefix
(
path
,
"../"
)
{
if
strings
.
HasPrefix
(
orig
,
"./"
)
&&
path
!=
".."
&&
!
strings
.
HasPrefix
(
path
,
"../"
)
{
path
=
"./"
+
path
}
return
path
...
...
libgo/go/database/sql/sql.go
View file @
42f20102
...
...
@@ -1357,16 +1357,7 @@ func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStra
cancel
:
cancel
,
ctx
:
ctx
,
}
go
func
(
tx
*
Tx
)
{
select
{
case
<-
tx
.
ctx
.
Done
()
:
if
!
tx
.
isDone
()
{
// Discard and close the connection used to ensure the transaction
// is closed and the resources are released.
tx
.
rollback
(
true
)
}
}
}(
tx
)
go
tx
.
awaitDone
()
return
tx
,
nil
}
...
...
@@ -1388,6 +1379,11 @@ func (db *DB) Driver() driver.Driver {
type
Tx
struct
{
db
*
DB
// closemu prevents the transaction from closing while there
// is an active query. It is held for read during queries
// and exclusively during close.
closemu
sync
.
RWMutex
// dc is owned exclusively until Commit or Rollback, at which point
// it's returned with putConn.
dc
*
driverConn
...
...
@@ -1413,6 +1409,20 @@ type Tx struct {
ctx
context
.
Context
}
// awaitDone blocks until the context in Tx is canceled and rolls back
// the transaction if it's not already done.
func
(
tx
*
Tx
)
awaitDone
()
{
// Wait for either the transaction to be committed or rolled
// back, or for the associated context to be closed.
<-
tx
.
ctx
.
Done
()
// Discard and close the connection used to ensure the
// transaction is closed and the resources are released. This
// rollback does nothing if the transaction has already been
// committed or rolled back.
tx
.
rollback
(
true
)
}
func
(
tx
*
Tx
)
isDone
()
bool
{
return
atomic
.
LoadInt32
(
&
tx
.
done
)
!=
0
}
...
...
@@ -1424,16 +1434,31 @@ var ErrTxDone = errors.New("sql: Transaction has already been committed or rolle
// close returns the connection to the pool and
// must only be called by Tx.rollback or Tx.Commit.
func
(
tx
*
Tx
)
close
(
err
error
)
{
tx
.
closemu
.
Lock
()
defer
tx
.
closemu
.
Unlock
()
tx
.
db
.
putConn
(
tx
.
dc
,
err
)
tx
.
cancel
()
tx
.
dc
=
nil
tx
.
txi
=
nil
}
// hookTxGrabConn specifies an optional hook to be called on
// a successful call to (*Tx).grabConn. For tests.
var
hookTxGrabConn
func
()
func
(
tx
*
Tx
)
grabConn
(
ctx
context
.
Context
)
(
*
driverConn
,
error
)
{
select
{
default
:
case
<-
ctx
.
Done
()
:
return
nil
,
ctx
.
Err
()
}
if
tx
.
isDone
()
{
return
nil
,
ErrTxDone
}
if
hookTxGrabConn
!=
nil
{
// test hook
hookTxGrabConn
()
}
return
tx
.
dc
,
nil
}
...
...
@@ -1503,6 +1528,9 @@ func (tx *Tx) Rollback() error {
// for the execution of the returned statement. The returned statement
// will run in the transaction context.
func
(
tx
*
Tx
)
PrepareContext
(
ctx
context
.
Context
,
query
string
)
(
*
Stmt
,
error
)
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
// TODO(bradfitz): We could be more efficient here and either
// provide a method to take an existing Stmt (created on
// perhaps a different Conn), and re-create it on this Conn if
...
...
@@ -1567,6 +1595,9 @@ func (tx *Tx) Prepare(query string) (*Stmt, error) {
// The returned statement operates within the transaction and will be closed
// when the transaction has been committed or rolled back.
func
(
tx
*
Tx
)
StmtContext
(
ctx
context
.
Context
,
stmt
*
Stmt
)
*
Stmt
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
// TODO(bradfitz): optimize this. Currently this re-prepares
// each time. This is fine for now to illustrate the API but
// we should really cache already-prepared statements
...
...
@@ -1618,6 +1649,9 @@ func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
// ExecContext executes a query that doesn't return rows.
// For example: an INSERT and UPDATE.
func
(
tx
*
Tx
)
ExecContext
(
ctx
context
.
Context
,
query
string
,
args
...
interface
{})
(
Result
,
error
)
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
dc
,
err
:=
tx
.
grabConn
(
ctx
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -1661,6 +1695,9 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
// QueryContext executes a query that returns rows, typically a SELECT.
func
(
tx
*
Tx
)
QueryContext
(
ctx
context
.
Context
,
query
string
,
args
...
interface
{})
(
*
Rows
,
error
)
{
tx
.
closemu
.
RLock
()
defer
tx
.
closemu
.
RUnlock
()
dc
,
err
:=
tx
.
grabConn
(
ctx
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -2038,25 +2075,21 @@ type Rows struct {
// closed value is 1 when the Rows is closed.
// Use atomic operations on value when checking value.
closed
int32
c
txClose
chan
struct
{}
// closed when Rows is closed, may be nul
l.
c
ancel
func
()
// called when Rows is closed, may be ni
l.
lastcols
[]
driver
.
Value
lasterr
error
// non-nil only if closed is true
closeStmt
*
driverStmt
// if non-nil, statement to Close on close
}
func
(
rs
*
Rows
)
initContextClose
(
ctx
context
.
Context
)
{
if
ctx
.
Done
()
==
context
.
Background
()
.
Done
()
{
return
}
ctx
,
rs
.
cancel
=
context
.
WithCancel
(
ctx
)
go
rs
.
awaitDone
(
ctx
)
}
rs
.
ctxClose
=
make
(
chan
struct
{})
go
func
()
{
select
{
case
<-
ctx
.
Done
()
:
rs
.
Close
()
case
<-
rs
.
ctxClose
:
}
}()
// awaitDone blocks until the rows are closed or the context canceled.
func
(
rs
*
Rows
)
awaitDone
(
ctx
context
.
Context
)
{
<-
ctx
.
Done
()
rs
.
Close
()
}
// Next prepares the next result row for reading with the Scan method. It
...
...
@@ -2314,7 +2347,9 @@ func (rs *Rows) Scan(dest ...interface{}) error {
return
nil
}
var
rowsCloseHook
func
(
*
Rows
,
*
error
)
// rowsCloseHook returns a function so tests may install the
// hook throug a test only mutex.
var
rowsCloseHook
=
func
()
func
(
*
Rows
,
*
error
)
{
return
nil
}
func
(
rs
*
Rows
)
isClosed
()
bool
{
return
atomic
.
LoadInt32
(
&
rs
.
closed
)
!=
0
...
...
@@ -2328,13 +2363,15 @@ func (rs *Rows) Close() error {
if
!
atomic
.
CompareAndSwapInt32
(
&
rs
.
closed
,
0
,
1
)
{
return
nil
}
if
rs
.
ctxClose
!=
nil
{
close
(
rs
.
ctxClose
)
}
err
:=
rs
.
rowsi
.
Close
()
if
fn
:=
rowsCloseHook
;
fn
!=
nil
{
if
fn
:=
rowsCloseHook
()
;
fn
!=
nil
{
fn
(
rs
,
&
err
)
}
if
rs
.
cancel
!=
nil
{
rs
.
cancel
()
}
if
rs
.
closeStmt
!=
nil
{
rs
.
closeStmt
.
Close
()
}
...
...
libgo/go/database/sql/sql_test.go
View file @
42f20102
...
...
@@ -14,6 +14,7 @@ import (
"runtime"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
)
...
...
@@ -326,9 +327,7 @@ func TestQueryContext(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
if
n
:=
db
.
numFreeConns
();
n
!=
1
{
t
.
Fatalf
(
"free conns after query hitting EOF = %d; want 1"
,
n
)
}
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
1
)
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
}
...
...
@@ -345,6 +344,18 @@ func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
return
false
}
// waitForFree checks db.numFreeConns until either it equals want or
// the maxWait time elapses.
func
waitForFree
(
t
*
testing
.
T
,
db
*
DB
,
maxWait
time
.
Duration
,
want
int
)
{
var
numFree
int
if
!
waitCondition
(
maxWait
,
5
*
time
.
Millisecond
,
func
()
bool
{
numFree
=
db
.
numFreeConns
()
return
numFree
==
want
})
{
t
.
Fatalf
(
"free conns after hitting EOF = %d; want %d"
,
numFree
,
want
)
}
}
func
TestQueryContextWait
(
t
*
testing
.
T
)
{
db
:=
newTestDB
(
t
,
"people"
)
defer
closeDB
(
t
,
db
)
...
...
@@ -361,9 +372,7 @@ func TestQueryContextWait(t *testing.T) {
}
// Verify closed rows connection after error condition.
if
n
:=
db
.
numFreeConns
();
n
!=
1
{
t
.
Fatalf
(
"free conns after query hitting EOF = %d; want 1"
,
n
)
}
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
1
)
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
}
...
...
@@ -388,13 +397,7 @@ func TestTxContextWait(t *testing.T) {
t
.
Fatalf
(
"expected QueryContext to error with context deadline exceeded but returned %v"
,
err
)
}
var
numFree
int
if
!
waitCondition
(
5
*
time
.
Second
,
5
*
time
.
Millisecond
,
func
()
bool
{
numFree
=
db
.
numFreeConns
()
return
numFree
==
0
})
{
t
.
Fatalf
(
"free conns after hitting EOF = %d; want 0"
,
numFree
)
}
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
0
)
// Ensure the dropped connection allows more connections to be made.
// Checked on DB Close.
...
...
@@ -471,9 +474,7 @@ func TestMultiResultSetQuery(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
if
n
:=
db
.
numFreeConns
();
n
!=
1
{
t
.
Fatalf
(
"free conns after query hitting EOF = %d; want 1"
,
n
)
}
waitForFree
(
t
,
db
,
5
*
time
.
Second
,
1
)
if
prepares
:=
numPrepares
(
t
,
db
)
-
prepares0
;
prepares
!=
1
{
t
.
Errorf
(
"executed %d Prepare statements; want 1"
,
prepares
)
}
...
...
@@ -1135,6 +1136,24 @@ func TestQueryRowClosingStmt(t *testing.T) {
}
}
var
atomicRowsCloseHook
atomic
.
Value
// of func(*Rows, *error)
func
init
()
{
rowsCloseHook
=
func
()
func
(
*
Rows
,
*
error
)
{
fn
,
_
:=
atomicRowsCloseHook
.
Load
()
.
(
func
(
*
Rows
,
*
error
))
return
fn
}
}
func
setRowsCloseHook
(
fn
func
(
*
Rows
,
*
error
))
{
if
fn
==
nil
{
// Can't change an atomic.Value back to nil, so set it to this
// no-op func instead.
fn
=
func
(
*
Rows
,
*
error
)
{}
}
atomicRowsCloseHook
.
Store
(
fn
)
}
// Test issue 6651
func
TestIssue6651
(
t
*
testing
.
T
)
{
db
:=
newTestDB
(
t
,
"people"
)
...
...
@@ -1147,6 +1166,7 @@ func TestIssue6651(t *testing.T) {
return
fmt
.
Errorf
(
want
)
}
defer
func
()
{
rowsCursorNextHook
=
nil
}()
err
:=
db
.
QueryRow
(
"SELECT|people|name|"
)
.
Scan
(
&
v
)
if
err
==
nil
||
err
.
Error
()
!=
want
{
t
.
Errorf
(
"error = %q; want %q"
,
err
,
want
)
...
...
@@ -1154,10 +1174,10 @@ func TestIssue6651(t *testing.T) {
rowsCursorNextHook
=
nil
want
=
"error in rows.Close"
rowsCloseHook
=
func
(
rows
*
Rows
,
err
*
error
)
{
setRowsCloseHook
(
func
(
rows
*
Rows
,
err
*
error
)
{
*
err
=
fmt
.
Errorf
(
want
)
}
defer
func
()
{
rowsCloseHook
=
nil
}(
)
}
)
defer
setRowsCloseHook
(
nil
)
err
=
db
.
QueryRow
(
"SELECT|people|name|"
)
.
Scan
(
&
v
)
if
err
==
nil
||
err
.
Error
()
!=
want
{
t
.
Errorf
(
"error = %q; want %q"
,
err
,
want
)
...
...
@@ -1830,7 +1850,9 @@ func TestStmtCloseDeps(t *testing.T) {
db
.
dumpDeps
(
t
)
}
if
len
(
stmt
.
css
)
>
nquery
{
if
!
waitCondition
(
5
*
time
.
Second
,
5
*
time
.
Millisecond
,
func
()
bool
{
return
len
(
stmt
.
css
)
<=
nquery
})
{
t
.
Errorf
(
"len(stmt.css) = %d; want <= %d"
,
len
(
stmt
.
css
),
nquery
)
}
...
...
@@ -2576,10 +2598,10 @@ func TestIssue6081(t *testing.T) {
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
rowsCloseHook
=
func
(
rows
*
Rows
,
err
*
error
)
{
setRowsCloseHook
(
func
(
rows
*
Rows
,
err
*
error
)
{
*
err
=
driver
.
ErrBadConn
}
defer
func
()
{
rowsCloseHook
=
nil
}(
)
}
)
defer
setRowsCloseHook
(
nil
)
for
i
:=
0
;
i
<
10
;
i
++
{
rows
,
err
:=
stmt
.
Query
()
if
err
!=
nil
{
...
...
@@ -2642,7 +2664,10 @@ func TestIssue18429(t *testing.T) {
if
err
!=
nil
{
return
}
rows
,
err
:=
tx
.
QueryContext
(
ctx
,
"WAIT|"
+
qwait
+
"|SELECT|people|name|"
)
// This is expected to give a cancel error many, but not all the time.
// Test failure will happen with a panic or other race condition being
// reported.
rows
,
_
:=
tx
.
QueryContext
(
ctx
,
"WAIT|"
+
qwait
+
"|SELECT|people|name|"
)
if
rows
!=
nil
{
rows
.
Close
()
}
...
...
@@ -2655,6 +2680,56 @@ func TestIssue18429(t *testing.T) {
time
.
Sleep
(
milliWait
*
3
*
time
.
Millisecond
)
}
// TestIssue18719 closes the context right before use. The sql.driverConn
// will nil out the ci on close in a lock, but if another process uses it right after
// it will panic with on the nil ref.
//
// See https://golang.org/cl/35550 .
func
TestIssue18719
(
t
*
testing
.
T
)
{
db
:=
newTestDB
(
t
,
"people"
)
defer
closeDB
(
t
,
db
)
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
tx
,
err
:=
db
.
BeginTx
(
ctx
,
nil
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
hookTxGrabConn
=
func
()
{
cancel
()
// Wait for the context to cancel and tx to rollback.
for
tx
.
isDone
()
==
false
{
time
.
Sleep
(
time
.
Millisecond
*
3
)
}
}
defer
func
()
{
hookTxGrabConn
=
nil
}()
// This call will grab the connection and cancel the context
// after it has done so. Code after must deal with the canceled state.
rows
,
err
:=
tx
.
QueryContext
(
ctx
,
"SELECT|people|name|"
)
if
err
!=
nil
{
rows
.
Close
()
t
.
Fatalf
(
"expected error %v but got %v"
,
nil
,
err
)
}
// Rows may be ignored because it will be closed when the context is canceled.
// Do not explicitly rollback. The rollback will happen from the
// canceled context.
// Wait for connections to return to pool.
var
numOpen
int
if
!
waitCondition
(
5
*
time
.
Second
,
5
*
time
.
Millisecond
,
func
()
bool
{
numOpen
=
db
.
numOpenConns
()
return
numOpen
==
0
})
{
t
.
Fatalf
(
"open conns after hitting EOF = %d; want 0"
,
numOpen
)
}
}
func
TestConcurrency
(
t
*
testing
.
T
)
{
doConcurrentTest
(
t
,
new
(
concurrentDBQueryTest
))
doConcurrentTest
(
t
,
new
(
concurrentDBExecTest
))
...
...
libgo/go/go/printer/nodes.go
View file @
42f20102
...
...
@@ -733,7 +733,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
case
*
ast
.
FuncLit
:
p
.
expr
(
x
.
Type
)
p
.
adjBlock
(
p
.
distanceFrom
(
x
.
Type
.
Pos
()),
blank
,
x
.
Body
)
p
.
funcBody
(
p
.
distanceFrom
(
x
.
Type
.
Pos
()),
blank
,
x
.
Body
)
case
*
ast
.
ParenExpr
:
if
_
,
hasParens
:=
x
.
X
.
(
*
ast
.
ParenExpr
);
hasParens
{
...
...
@@ -825,6 +825,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
if
x
.
Type
!=
nil
{
p
.
expr1
(
x
.
Type
,
token
.
HighestPrec
,
depth
)
}
p
.
level
++
p
.
print
(
x
.
Lbrace
,
token
.
LBRACE
)
p
.
exprList
(
x
.
Lbrace
,
x
.
Elts
,
1
,
commaTerm
,
x
.
Rbrace
)
// do not insert extra line break following a /*-style comment
...
...
@@ -837,6 +838,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
mode
|=
noExtraBlank
}
p
.
print
(
mode
,
x
.
Rbrace
,
token
.
RBRACE
,
mode
)
p
.
level
--
case
*
ast
.
Ellipsis
:
p
.
print
(
token
.
ELLIPSIS
)
...
...
@@ -1557,18 +1559,23 @@ func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
return
bodySize
}
// adjBlock prints an "adjacent" block (e.g., a for-loop or function body) following
// a header (e.g., a for-loop control clause or function signature) of given headerSize.
// funcBody prints a function body following a function header of given headerSize.
// If the header's and block's size are "small enough" and the block is "simple enough",
// the block is printed on the current line, without line breaks, spaced from the header
// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
// lines for the block's statements and its closing "}".
//
func
(
p
*
printer
)
adjBlock
(
headerSize
int
,
sep
whiteSpace
,
b
*
ast
.
BlockStmt
)
{
func
(
p
*
printer
)
funcBody
(
headerSize
int
,
sep
whiteSpace
,
b
*
ast
.
BlockStmt
)
{
if
b
==
nil
{
return
}
// save/restore composite literal nesting level
defer
func
(
level
int
)
{
p
.
level
=
level
}(
p
.
level
)
p
.
level
=
0
const
maxSize
=
100
if
headerSize
+
p
.
bodySize
(
b
,
maxSize
)
<=
maxSize
{
p
.
print
(
sep
,
b
.
Lbrace
,
token
.
LBRACE
)
...
...
@@ -1613,7 +1620,7 @@ func (p *printer) funcDecl(d *ast.FuncDecl) {
}
p
.
expr
(
d
.
Name
)
p
.
signature
(
d
.
Type
.
Params
,
d
.
Type
.
Results
)
p
.
adjBlock
(
p
.
distanceFrom
(
d
.
Pos
()),
vtab
,
d
.
Body
)
p
.
funcBody
(
p
.
distanceFrom
(
d
.
Pos
()),
vtab
,
d
.
Body
)
}
func
(
p
*
printer
)
decl
(
decl
ast
.
Decl
)
{
...
...
libgo/go/go/printer/printer.go
View file @
42f20102
...
...
@@ -58,6 +58,7 @@ type printer struct {
// Current state
output
[]
byte
// raw printer result
indent
int
// current indentation
level
int
// level == 0: outside composite literal; level > 0: inside composite literal
mode
pmode
// current printer mode
impliedSemi
bool
// if set, a linebreak implies a semicolon
lastTok
token
.
Token
// last token printed (token.ILLEGAL if it's whitespace)
...
...
@@ -744,15 +745,19 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
// follows on the same line but is not a comma, and not a "closing"
// token immediately following its corresponding "opening" token,
// add an extra separator unless explicitly disabled. Use a blank
// as separator unless we have pending linebreaks and they are not
// disabled, in which case we want a linebreak (issue 15137).
// as separator unless we have pending linebreaks, they are not
// disabled, and we are outside a composite literal, in which case
// we want a linebreak (issue 15137).
// TODO(gri) This has become overly complicated. We should be able
// to track whether we're inside an expression or statement and
// use that information to decide more directly.
needsLinebreak
:=
false
if
p
.
mode
&
noExtraBlank
==
0
&&
last
.
Text
[
1
]
==
'*'
&&
p
.
lineFor
(
last
.
Pos
())
==
next
.
Line
&&
tok
!=
token
.
COMMA
&&
(
tok
!=
token
.
RPAREN
||
p
.
prevOpen
==
token
.
LPAREN
)
&&
(
tok
!=
token
.
RBRACK
||
p
.
prevOpen
==
token
.
LBRACK
)
{
if
p
.
containsLinebreak
()
&&
p
.
mode
&
noExtraLinebreak
==
0
{
if
p
.
containsLinebreak
()
&&
p
.
mode
&
noExtraLinebreak
==
0
&&
p
.
level
==
0
{
needsLinebreak
=
true
}
else
{
p
.
writeByte
(
' '
,
1
)
...
...
libgo/go/go/printer/testdata/comments2.golden
View file @
42f20102
...
...
@@ -103,3 +103,62 @@ label:
mask
:=
uint64
(
1
)<<
c
-
1
//
Allocation
mask
used
:=
atomic
.
LoadUint64
(&
h
.
used
)
//
Current
allocations
}
//
Test
cases
for
issue
18782
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
var
_
=
T
{
/*
a
*/
0
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
,
}
var
_
=
T
{
/*
a
*/
{}}
var
_
=
T
{
/*
a
*/
/*
b
*/
{}}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
{},
}
var
_
=
[]
T
{
func
()
{
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
},
}
libgo/go/go/printer/testdata/comments2.input
View file @
42f20102
...
...
@@ -103,3 +103,66 @@ label:
mask
:=
uint64
(
1
)<<
c
-
1
//
Allocation
mask
used
:=
atomic
.
LoadUint64
(&
h
.
used
)
//
Current
allocations
}
//
Test
cases
for
issue
18782
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
var
_
=
T
{
/*
a
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
0
,
}
var
_
=
T
{
/*
a
*/
/*
b
*/
0
,
}
var
_
=
T
{
/*
a
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
/*
c
*/
/*
d
*/
{},
}
var
_
=
T
{
/*
a
*/
/*
b
*/
{},
}
var
_
=
[]
T
{
func
()
{
var
_
=
[][]
int
{
/*
a
,
b
,
c
,
d
,
e
*/
/*
a
*/
{
0
,
0
,
0
,
0
,
0
},
/*
b
*/
{
0
,
5
,
4
,
4
,
4
},
/*
c
*/
{
0
,
4
,
5
,
4
,
4
},
/*
d
*/
{
0
,
4
,
4
,
5
,
4
},
/*
e
*/
{
0
,
4
,
4
,
4
,
5
},
}
},
}
libgo/go/net/http/client.go
View file @
42f20102
...
...
@@ -413,11 +413,12 @@ func (c *Client) checkRedirect(req *Request, via []*Request) error {
// redirectBehavior describes what should happen when the
// client encounters a 3xx status code from the server
func
redirectBehavior
(
reqMethod
string
,
resp
*
Response
,
ireq
*
Request
)
(
redirectMethod
string
,
shouldRedirect
bool
)
{
func
redirectBehavior
(
reqMethod
string
,
resp
*
Response
,
ireq
*
Request
)
(
redirectMethod
string
,
shouldRedirect
,
includeBody
bool
)
{
switch
resp
.
StatusCode
{
case
301
,
302
,
303
:
redirectMethod
=
reqMethod
shouldRedirect
=
true
includeBody
=
false
// RFC 2616 allowed automatic redirection only with GET and
// HEAD requests. RFC 7231 lifts this restriction, but we still
...
...
@@ -429,6 +430,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
case
307
,
308
:
redirectMethod
=
reqMethod
shouldRedirect
=
true
includeBody
=
true
// Treat 307 and 308 specially, since they're new in
// Go 1.8, and they also require re-sending the request body.
...
...
@@ -449,7 +451,7 @@ func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirect
shouldRedirect
=
false
}
}
return
redirectMethod
,
shouldRedirect
return
redirectMethod
,
shouldRedirect
,
includeBody
}
// Do sends an HTTP request and returns an HTTP response, following
...
...
@@ -492,11 +494,14 @@ func (c *Client) Do(req *Request) (*Response, error) {
}
var
(
deadline
=
c
.
deadline
()
reqs
[]
*
Request
resp
*
Response
copyHeaders
=
c
.
makeHeadersCopier
(
req
)
deadline
=
c
.
deadline
()
reqs
[]
*
Request
resp
*
Response
copyHeaders
=
c
.
makeHeadersCopier
(
req
)
// Redirect behavior:
redirectMethod
string
includeBody
bool
)
uerr
:=
func
(
err
error
)
error
{
req
.
closeBody
()
...
...
@@ -534,7 +539,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
Cancel
:
ireq
.
Cancel
,
ctx
:
ireq
.
ctx
,
}
if
ireq
.
GetBody
!=
nil
{
if
i
ncludeBody
&&
i
req
.
GetBody
!=
nil
{
req
.
Body
,
err
=
ireq
.
GetBody
()
if
err
!=
nil
{
return
nil
,
uerr
(
err
)
...
...
@@ -598,7 +603,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
}
var
shouldRedirect
bool
redirectMethod
,
shouldRedirect
=
redirectBehavior
(
req
.
Method
,
resp
,
reqs
[
0
])
redirectMethod
,
shouldRedirect
,
includeBody
=
redirectBehavior
(
req
.
Method
,
resp
,
reqs
[
0
])
if
!
shouldRedirect
{
return
resp
,
nil
}
...
...
libgo/go/net/http/client_test.go
View file @
42f20102
...
...
@@ -360,25 +360,25 @@ func TestPostRedirects(t *testing.T) {
wantSegments
:=
[]
string
{
`POST / "first"`
,
`POST /?code=301&next=302 "c301"`
,
`GET /?code=302 "
c301
"`
,
`GET / "
c301
"`
,
`GET /?code=302 ""`
,
`GET / ""`
,
`POST /?code=302&next=302 "c302"`
,
`GET /?code=302 "
c302
"`
,
`GET / "
c302
"`
,
`GET /?code=302 ""`
,
`GET / ""`
,
`POST /?code=303&next=301 "c303wc301"`
,
`GET /?code=301 "
c303wc301
"`
,
`GET / "
c303wc301
"`
,
`GET /?code=301 ""`
,
`GET / ""`
,
`POST /?code=304 "c304"`
,
`POST /?code=305 "c305"`
,
`POST /?code=307&next=303,308,302 "c307"`
,
`POST /?code=303&next=308,302 "c307"`
,
`GET /?code=308&next=302 "
c307
"`
,
`GET /?code=308&next=302 ""`
,
`GET /?code=302 "c307"`
,
`GET / "
c307
"`
,
`GET / ""`
,
`POST /?code=308&next=302,301 "c308"`
,
`POST /?code=302&next=301 "c308"`
,
`GET /?code=301 "
c308
"`
,
`GET / "
c308
"`
,
`GET /?code=301 ""`
,
`GET / ""`
,
`POST /?code=404 "c404"`
,
}
want
:=
strings
.
Join
(
wantSegments
,
"
\n
"
)
...
...
@@ -399,20 +399,20 @@ func TestDeleteRedirects(t *testing.T) {
wantSegments
:=
[]
string
{
`DELETE / "first"`
,
`DELETE /?code=301&next=302,308 "c301"`
,
`GET /?code=302&next=308 "
c301
"`
,
`GET /?code=308 "
c301
"`
,
`GET /?code=302&next=308 ""`
,
`GET /?code=308 ""`
,
`GET / "c301"`
,
`DELETE /?code=302&next=302 "c302"`
,
`GET /?code=302 "
c302
"`
,
`GET / "
c302
"`
,
`GET /?code=302 ""`
,
`GET / ""`
,
`DELETE /?code=303 "c303"`
,
`GET / "
c303
"`
,
`GET / ""`
,
`DELETE /?code=307&next=301,308,303,302,304 "c307"`
,
`DELETE /?code=301&next=308,303,302,304 "c307"`
,
`GET /?code=308&next=303,302,304 "
c307
"`
,
`GET /?code=308&next=303,302,304 ""`
,
`GET /?code=303&next=302,304 "c307"`
,
`GET /?code=302&next=304 "
c307
"`
,
`GET /?code=304 "
c307
"`
,
`GET /?code=302&next=304 ""`
,
`GET /?code=304 ""`
,
`DELETE /?code=308&next=307 "c308"`
,
`DELETE /?code=307 "c308"`
,
`DELETE / "c308"`
,
...
...
@@ -432,7 +432,11 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
ts
=
httptest
.
NewServer
(
HandlerFunc
(
func
(
w
ResponseWriter
,
r
*
Request
)
{
log
.
Lock
()
slurp
,
_
:=
ioutil
.
ReadAll
(
r
.
Body
)
fmt
.
Fprintf
(
&
log
.
Buffer
,
"%s %s %q
\n
"
,
r
.
Method
,
r
.
RequestURI
,
slurp
)
fmt
.
Fprintf
(
&
log
.
Buffer
,
"%s %s %q"
,
r
.
Method
,
r
.
RequestURI
,
slurp
)
if
cl
:=
r
.
Header
.
Get
(
"Content-Length"
);
r
.
Method
==
"GET"
&&
len
(
slurp
)
==
0
&&
(
r
.
ContentLength
!=
0
||
cl
!=
""
)
{
fmt
.
Fprintf
(
&
log
.
Buffer
,
" (but with body=%T, content-length = %v, %q)"
,
r
.
Body
,
r
.
ContentLength
,
cl
)
}
log
.
WriteByte
(
'\n'
)
log
.
Unlock
()
urlQuery
:=
r
.
URL
.
Query
()
if
v
:=
urlQuery
.
Get
(
"code"
);
v
!=
""
{
...
...
@@ -475,7 +479,24 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa
want
=
strings
.
TrimSpace
(
want
)
if
got
!=
want
{
t
.
Errorf
(
"Log differs.
\n
Got:
\n
%s
\n
Want:
\n
%s
\n
"
,
got
,
want
)
got
,
want
,
lines
:=
removeCommonLines
(
got
,
want
)
t
.
Errorf
(
"Log differs after %d common lines.
\n\n
Got:
\n
%s
\n\n
Want:
\n
%s
\n
"
,
lines
,
got
,
want
)
}
}
func
removeCommonLines
(
a
,
b
string
)
(
asuffix
,
bsuffix
string
,
commonLines
int
)
{
for
{
nl
:=
strings
.
IndexByte
(
a
,
'\n'
)
if
nl
<
0
{
return
a
,
b
,
commonLines
}
line
:=
a
[
:
nl
+
1
]
if
!
strings
.
HasPrefix
(
b
,
line
)
{
return
a
,
b
,
commonLines
}
commonLines
++
a
=
a
[
len
(
line
)
:
]
b
=
b
[
len
(
line
)
:
]
}
}
...
...
libgo/go/net/http/serve_test.go
View file @
42f20102
...
...
@@ -5277,7 +5277,7 @@ func TestServerHijackGetsBackgroundByte_big(t *testing.T) {
defer
conn
.
Close
()
slurp
,
err
:=
ioutil
.
ReadAll
(
buf
.
Reader
)
if
err
!=
nil
{
t
.
Error
(
"Copy: %v"
,
err
)
t
.
Error
f
(
"Copy: %v"
,
err
)
}
allX
:=
true
for
_
,
v
:=
range
slurp
{
...
...
libgo/merge.sh
View file @
42f20102
...
...
@@ -71,7 +71,9 @@ merge() {
elif
test
-f
${
old
}
;
then
# The file exists in the old version.
if
!
test
-f
${
libgo
}
;
then
echo
"merge.sh:
$name
: skipping: exists in old and new git, but not in libgo"
if
!
cmp
-s
${
old
}
${
new
}
;
then
echo
"merge.sh:
$name
: skipping: exists in old and new git, but not in libgo"
fi
continue
fi
if
cmp
-s
${
old
}
${
libgo
}
;
then
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment