Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
39101613
Commit
39101613
authored
Feb 25, 2010
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gc: implement []int(string) and []byte(string)
R=ken2 CC=golang-dev
https://golang.org/cl/224060
parent
b86c0b0c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
175 additions
and
14 deletions
+175
-14
src/cmd/gc/builtin.c.boot
src/cmd/gc/builtin.c.boot
+2
-0
src/cmd/gc/go.h
src/cmd/gc/go.h
+3
-2
src/cmd/gc/runtime.go
src/cmd/gc/runtime.go
+2
-0
src/cmd/gc/typecheck.c
src/cmd/gc/typecheck.c
+58
-2
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+22
-10
src/pkg/runtime/string.cgo
src/pkg/runtime/string.cgo
+31
-0
test/convlit.go
test/convlit.go
+27
-0
test/string_lit.go
test/string_lit.go
+30
-0
No files found.
src/cmd/gc/builtin.c.boot
View file @
39101613
...
@@ -26,6 +26,8 @@ char *runtimeimport =
...
@@ -26,6 +26,8 @@ char *runtimeimport =
"func \"\".intstring (? int64) string\n"
"func \"\".intstring (? int64) string\n"
"func \"\".slicebytetostring (? []uint8) string\n"
"func \"\".slicebytetostring (? []uint8) string\n"
"func \"\".sliceinttostring (? []int) string\n"
"func \"\".sliceinttostring (? []int) string\n"
"func \"\".stringtoslicebyte (? string) []uint8\n"
"func \"\".stringtosliceint (? string) []int\n"
"func \"\".stringiter (? string, ? int) int\n"
"func \"\".stringiter (? string, ? int) int\n"
"func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
"func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
"func \"\".slicecopy (to any, fr any, wid uint32) int\n"
"func \"\".slicecopy (to any, fr any, wid uint32) int\n"
...
...
src/cmd/gc/go.h
View file @
39101613
...
@@ -351,6 +351,7 @@ enum
...
@@ -351,6 +351,7 @@ enum
OAPPENDSTR
,
OAPPENDSTR
,
OARRAY
,
OARRAY
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OSTRARRAYBYTE
,
OSTRARRAYRUNE
,
OAS
,
OAS2
,
OAS2MAPW
,
OAS2FUNC
,
OAS2RECV
,
OAS2MAPR
,
OAS2DOTTYPE
,
OASOP
,
OAS
,
OAS2
,
OAS2MAPW
,
OAS2FUNC
,
OAS2RECV
,
OAS2MAPR
,
OAS2DOTTYPE
,
OASOP
,
OBAD
,
OBAD
,
OCALL
,
OCALLFUNC
,
OCALLMETH
,
OCALLINTER
,
OCALL
,
OCALLFUNC
,
OCALLMETH
,
OCALLINTER
,
...
@@ -411,7 +412,7 @@ enum
...
@@ -411,7 +412,7 @@ enum
OTINTER
,
OTINTER
,
OTFUNC
,
OTFUNC
,
OTARRAY
,
OTARRAY
,
// misc
// misc
ODDD
,
ODDD
,
...
@@ -458,7 +459,7 @@ enum
...
@@ -458,7 +459,7 @@ enum
TIDEAL
,
// 32
TIDEAL
,
// 32
TNIL
,
TNIL
,
TBLANK
,
TBLANK
,
// pseudo-type for frame layout
// pseudo-type for frame layout
TFUNCARGS
,
TFUNCARGS
,
TCHANARGS
,
TCHANARGS
,
...
...
src/cmd/gc/runtime.go
View file @
39101613
...
@@ -38,6 +38,8 @@ func indexstring(string, int) byte
...
@@ -38,6 +38,8 @@ func indexstring(string, int) byte
func
intstring
(
int64
)
string
func
intstring
(
int64
)
string
func
slicebytetostring
([]
byte
)
string
func
slicebytetostring
([]
byte
)
string
func
sliceinttostring
([]
int
)
string
func
sliceinttostring
([]
int
)
string
func
stringtoslicebyte
(
string
)
[]
byte
func
stringtosliceint
(
string
)
[]
int
func
stringiter
(
string
,
int
)
int
func
stringiter
(
string
,
int
)
int
func
stringiter2
(
string
,
int
)
(
retk
int
,
retv
int
)
func
stringiter2
(
string
,
int
)
(
retk
int
,
retv
int
)
func
slicecopy
(
to
any
,
fr
any
,
wid
uint32
)
int
func
slicecopy
(
to
any
,
fr
any
,
wid
uint32
)
int
...
...
src/cmd/gc/typecheck.c
View file @
39101613
...
@@ -32,6 +32,7 @@ static void checklvalue(Node*, char*);
...
@@ -32,6 +32,7 @@ static void checklvalue(Node*, char*);
static
void
checkassign
(
Node
*
);
static
void
checkassign
(
Node
*
);
static
void
checkassignlist
(
NodeList
*
);
static
void
checkassignlist
(
NodeList
*
);
static
void
toslice
(
Node
**
);
static
void
toslice
(
Node
**
);
static
void
stringtoarraylit
(
Node
**
);
void
void
typechecklist
(
NodeList
*
l
,
int
top
)
typechecklist
(
NodeList
*
l
,
int
top
)
...
@@ -835,6 +836,13 @@ reswitch:
...
@@ -835,6 +836,13 @@ reswitch:
n
=
typecheckconv
(
n
,
n
->
left
,
n
->
type
,
1
,
"conversion"
);
n
=
typecheckconv
(
n
,
n
->
left
,
n
->
type
,
1
,
"conversion"
);
if
(
n
->
type
==
T
)
if
(
n
->
type
==
T
)
goto
error
;
goto
error
;
switch
(
n
->
op
)
{
case
OSTRARRAYBYTE
:
case
OSTRARRAYRUNE
:
if
(
n
->
left
->
op
==
OLITERAL
)
stringtoarraylit
(
&
n
);
break
;
}
goto
ret
;
goto
ret
;
case
OMAKE
:
case
OMAKE
:
...
@@ -1406,6 +1414,18 @@ checkconv(Type *nt, Type *t, int explicit, int *op, int *et, char *desc)
...
@@ -1406,6 +1414,18 @@ checkconv(Type *nt, Type *t, int explicit, int *op, int *et, char *desc)
}
}
}
}
// from string
if
(
istype
(
nt
,
TSTRING
)
&&
isslice
(
t
)
&&
t
->
sym
==
S
)
{
switch
(
t
->
type
->
etype
)
{
case
TUINT8
:
*
op
=
OSTRARRAYBYTE
;
return
1
;
case
TINT
:
*
op
=
OSTRARRAYRUNE
;
return
1
;
}
}
// convert to unsafe pointer
// convert to unsafe pointer
if
(
isptrto
(
t
,
TANY
)
if
(
isptrto
(
t
,
TANY
)
&&
(
isptr
[
nt
->
etype
]
||
nt
->
etype
==
TUINTPTR
))
&&
(
isptr
[
nt
->
etype
]
||
nt
->
etype
==
TUINTPTR
))
...
@@ -1534,7 +1554,7 @@ typecheckaste(int op, Type *tstruct, NodeList *nl, char *desc)
...
@@ -1534,7 +1554,7 @@ typecheckaste(int op, Type *tstruct, NodeList *nl, char *desc)
// TODO(rsc): drop first if in DDD cleanup
// TODO(rsc): drop first if in DDD cleanup
if
(
t
->
etype
!=
TINTER
)
if
(
t
->
etype
!=
TINTER
)
if
(
checkconv
(
nl
->
n
->
type
,
t
->
type
,
0
,
&
xx
,
&
yy
,
desc
)
<
0
)
if
(
checkconv
(
nl
->
n
->
type
,
t
->
type
,
0
,
&
xx
,
&
yy
,
desc
)
<
0
)
yyerror
(
"cannot use %+N as type %T in %s"
,
nl
->
n
,
t
->
type
,
desc
);
yyerror
(
"cannot use %+N as type %T in %s"
,
nl
->
n
,
t
->
type
,
desc
);
}
}
goto
out
;
goto
out
;
}
}
...
@@ -1587,7 +1607,7 @@ exportassignok(Type *t, char *desc)
...
@@ -1587,7 +1607,7 @@ exportassignok(Type *t, char *desc)
// it only happens for fields in a ... struct.
// it only happens for fields in a ... struct.
if
(
s
!=
nil
&&
!
exportname
(
s
->
name
)
&&
s
->
pkg
!=
localpkg
)
{
if
(
s
!=
nil
&&
!
exportname
(
s
->
name
)
&&
s
->
pkg
!=
localpkg
)
{
char
*
prefix
;
char
*
prefix
;
prefix
=
""
;
prefix
=
""
;
if
(
desc
!=
nil
)
if
(
desc
!=
nil
)
prefix
=
" in "
;
prefix
=
" in "
;
...
@@ -2164,3 +2184,39 @@ typecheckfunc(Node *n)
...
@@ -2164,3 +2184,39 @@ typecheckfunc(Node *n)
if
(
rcvr
!=
nil
&&
n
->
shortname
!=
N
&&
!
isblank
(
n
->
shortname
))
if
(
rcvr
!=
nil
&&
n
->
shortname
!=
N
&&
!
isblank
(
n
->
shortname
))
addmethod
(
n
->
shortname
->
sym
,
t
,
1
);
addmethod
(
n
->
shortname
->
sym
,
t
,
1
);
}
}
static
void
stringtoarraylit
(
Node
**
np
)
{
int32
i
;
NodeList
*
l
;
Strlit
*
s
;
char
*
p
,
*
ep
;
Rune
r
;
Node
*
nn
,
*
n
;
n
=
*
np
;
if
(
n
->
left
->
op
!=
OLITERAL
||
n
->
left
->
val
.
ctype
!=
CTSTR
)
fatal
(
"stringtoarraylit %N"
,
n
);
s
=
n
->
left
->
val
.
u
.
sval
;
l
=
nil
;
p
=
s
->
s
;
ep
=
s
->
s
+
s
->
len
;
i
=
0
;
if
(
n
->
type
->
type
->
etype
==
TUINT8
)
{
// raw []byte
while
(
p
<
ep
)
l
=
list
(
l
,
nod
(
OKEY
,
nodintconst
(
i
++
),
nodintconst
((
uchar
)
*
p
++
)));
}
else
{
// utf-8 []int
while
(
p
<
ep
)
{
p
+=
chartorune
(
&
r
,
p
);
l
=
list
(
l
,
nod
(
OKEY
,
nodintconst
(
i
++
),
nodintconst
(
r
)));
}
}
nn
=
nod
(
OCOMPLIT
,
N
,
typenod
(
n
->
type
));
nn
->
list
=
l
;
typecheck
(
&
nn
,
Erv
);
*
np
=
nn
;
}
src/cmd/gc/walk.c
View file @
39101613
...
@@ -8,6 +8,7 @@ static Node* walkprint(Node*, NodeList**, int);
...
@@ -8,6 +8,7 @@ static Node* walkprint(Node*, NodeList**, int);
static
Node
*
conv
(
Node
*
,
Type
*
);
static
Node
*
conv
(
Node
*
,
Type
*
);
static
Node
*
mapfn
(
char
*
,
Type
*
);
static
Node
*
mapfn
(
char
*
,
Type
*
);
static
Node
*
makenewvar
(
Type
*
,
NodeList
**
,
Node
**
);
static
Node
*
makenewvar
(
Type
*
,
NodeList
**
,
Node
**
);
enum
enum
{
{
Inone
,
Inone
,
...
@@ -122,7 +123,7 @@ static void
...
@@ -122,7 +123,7 @@ static void
domethod
(
Node
*
n
)
domethod
(
Node
*
n
)
{
{
Node
*
nt
;
Node
*
nt
;
nt
=
n
->
type
->
nname
;
nt
=
n
->
type
->
nname
;
typecheck
(
&
nt
,
Etype
);
typecheck
(
&
nt
,
Etype
);
if
(
nt
->
type
==
T
)
{
if
(
nt
->
type
==
T
)
{
...
@@ -142,7 +143,7 @@ walkdeftype(Node *n)
...
@@ -142,7 +143,7 @@ walkdeftype(Node *n)
int
maplineno
,
embedlineno
,
lno
;
int
maplineno
,
embedlineno
,
lno
;
Type
*
t
;
Type
*
t
;
NodeList
*
l
;
NodeList
*
l
;
nwalkdeftype
++
;
nwalkdeftype
++
;
lno
=
lineno
;
lno
=
lineno
;
setlineno
(
n
);
setlineno
(
n
);
...
@@ -183,7 +184,7 @@ walkdeftype(Node *n)
...
@@ -183,7 +184,7 @@ walkdeftype(Node *n)
ret:
ret:
lineno
=
lno
;
lineno
=
lno
;
// if there are no type definitions going on, it's safe to
// if there are no type definitions going on, it's safe to
// try to resolve the method types for the interfaces
// try to resolve the method types for the interfaces
// we just read.
// we just read.
...
@@ -868,7 +869,7 @@ walkexpr(Node **np, NodeList **init)
...
@@ -868,7 +869,7 @@ walkexpr(Node **np, NodeList **init)
case
OINDEX
:
case
OINDEX
:
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
walkexpr
(
&
n
->
right
,
init
);
// if range of type cannot exceed static array bound,
// if range of type cannot exceed static array bound,
// disable bounds check
// disable bounds check
if
(
!
isslice
(
n
->
left
->
type
))
if
(
!
isslice
(
n
->
left
->
type
))
...
@@ -1092,10 +1093,20 @@ walkexpr(Node **np, NodeList **init)
...
@@ -1092,10 +1093,20 @@ walkexpr(Node **np, NodeList **init)
goto
ret
;
goto
ret
;
case
OARRAYRUNESTR
:
case
OARRAYRUNESTR
:
// sliceinttostring([]
byte
) string;
// sliceinttostring([]
int
) string;
n
=
mkcall
(
"sliceinttostring"
,
n
->
type
,
init
,
n
->
left
);
n
=
mkcall
(
"sliceinttostring"
,
n
->
type
,
init
,
n
->
left
);
goto
ret
;
goto
ret
;
case
OSTRARRAYBYTE
:
// stringtoslicebyte(string) []byte;
n
=
mkcall
(
"stringtoslicebyte"
,
n
->
type
,
init
,
n
->
left
);
goto
ret
;
case
OSTRARRAYRUNE
:
// stringtosliceint(string) []int
n
=
mkcall
(
"stringtosliceint"
,
n
->
type
,
init
,
n
->
left
);
goto
ret
;
case
OCMPIFACE
:
case
OCMPIFACE
:
// ifaceeq(i1 any-1, i2 any-2) (ret bool);
// ifaceeq(i1 any-1, i2 any-2) (ret bool);
if
(
!
eqtype
(
n
->
left
->
type
,
n
->
right
->
type
))
if
(
!
eqtype
(
n
->
left
->
type
,
n
->
right
->
type
))
...
@@ -1117,6 +1128,7 @@ walkexpr(Node **np, NodeList **init)
...
@@ -1117,6 +1128,7 @@ walkexpr(Node **np, NodeList **init)
case
OARRAYLIT
:
case
OARRAYLIT
:
case
OMAPLIT
:
case
OMAPLIT
:
case
OSTRUCTLIT
:
case
OSTRUCTLIT
:
arraylit:
nvar
=
nod
(
OXXX
,
N
,
N
);
nvar
=
nod
(
OXXX
,
N
,
N
);
tempname
(
nvar
,
n
->
type
);
tempname
(
nvar
,
n
->
type
);
anylit
(
n
,
nvar
,
init
);
anylit
(
n
,
nvar
,
init
);
...
@@ -1448,18 +1460,18 @@ mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init)
...
@@ -1448,18 +1460,18 @@ mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init)
{
{
Node
*
a
,
*
n
;
Node
*
a
,
*
n
;
Type
*
tslice
;
Type
*
tslice
;
tslice
=
typ
(
TARRAY
);
tslice
=
typ
(
TARRAY
);
tslice
->
type
=
l
->
type
->
type
;
tslice
->
type
=
l
->
type
->
type
;
tslice
->
bound
=
-
1
;
tslice
->
bound
=
-
1
;
n
=
nod
(
OCOMPLIT
,
N
,
typenod
(
tslice
));
n
=
nod
(
OCOMPLIT
,
N
,
typenod
(
tslice
));
n
->
list
=
lr0
;
n
->
list
=
lr0
;
typecheck
(
&
n
,
Erv
);
typecheck
(
&
n
,
Erv
);
if
(
n
->
type
==
T
)
if
(
n
->
type
==
T
)
fatal
(
"mkdotargslice: typecheck failed"
);
fatal
(
"mkdotargslice: typecheck failed"
);
walkexpr
(
&
n
,
init
);
walkexpr
(
&
n
,
init
);
a
=
nod
(
OAS
,
nodarg
(
l
,
fp
),
n
);
a
=
nod
(
OAS
,
nodarg
(
l
,
fp
),
n
);
nn
=
list
(
nn
,
convas
(
a
,
init
));
nn
=
list
(
nn
,
convas
(
a
,
init
));
return
nn
;
return
nn
;
...
@@ -1758,7 +1770,7 @@ walkprint(Node *nn, NodeList **init, int defer)
...
@@ -1758,7 +1770,7 @@ walkprint(Node *nn, NodeList **init, int defer)
n
=
nod
(
OCONV
,
n
,
N
);
n
=
nod
(
OCONV
,
n
,
N
);
n
->
type
=
t
;
n
->
type
=
t
;
}
}
if
(
defer
)
{
if
(
defer
)
{
intypes
=
list
(
intypes
,
nod
(
ODCLFIELD
,
N
,
typenod
(
t
)));
intypes
=
list
(
intypes
,
nod
(
ODCLFIELD
,
N
,
typenod
(
t
)));
args
=
list
(
args
,
n
);
args
=
list
(
args
,
n
);
...
@@ -1788,7 +1800,7 @@ walkprint(Node *nn, NodeList **init, int defer)
...
@@ -1788,7 +1800,7 @@ walkprint(Node *nn, NodeList **init, int defer)
calls
=
list
(
calls
,
mkcall
(
"printnl"
,
T
,
nil
));
calls
=
list
(
calls
,
mkcall
(
"printnl"
,
T
,
nil
));
typechecklist
(
calls
,
Etop
);
typechecklist
(
calls
,
Etop
);
walkexprlist
(
calls
,
init
);
walkexprlist
(
calls
,
init
);
if
(
op
==
OPANIC
||
op
==
OPANICN
)
if
(
op
==
OPANIC
||
op
==
OPANICN
)
r
=
mkcall
(
"panicl"
,
T
,
nil
);
r
=
mkcall
(
"panicl"
,
T
,
nil
);
else
else
...
...
src/pkg/runtime/string.cgo
View file @
39101613
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
package
runtime
package
runtime
#
include
"runtime.h"
#
include
"runtime.h"
#
include
"malloc.h"
String
emptystring
;
String
emptystring
;
...
@@ -210,6 +211,12 @@ func slicebytetostring(b Slice) (s String) {
...
@@ -210,6 +211,12 @@ func slicebytetostring(b Slice) (s String) {
mcpy
(
s
.
str
,
b
.
array
,
s
.
len
);
mcpy
(
s
.
str
,
b
.
array
,
s
.
len
);
}
}
func
stringtoslicebyte
(
s
String
)
(
b
Slice
)
{
b
.
array
=
mallocgc
(
s
.
len
,
RefNoPointers
,
1
,
1
);
b
.
len
=
s
.
len
;
b
.
cap
=
s
.
len
;
mcpy
(
b
.
array
,
s
.
str
,
s
.
len
);
}
func
sliceinttostring
(
b
Slice
)
(
s
String
)
{
func
sliceinttostring
(
b
Slice
)
(
s
String
)
{
int32
siz1
,
siz2
,
i
;
int32
siz1
,
siz2
,
i
;
...
@@ -233,6 +240,30 @@ func sliceinttostring(b Slice) (s String) {
...
@@ -233,6 +240,30 @@ func sliceinttostring(b Slice) (s String) {
s
.
len
=
siz2
;
s
.
len
=
siz2
;
}
}
func
stringtosliceint
(
s
String
)
(
b
Slice
)
{
int32
n
;
int32
dum
,
*
r
;
uint8
*
p
,
*
ep
;
//
two
passes
.
//
unlike
sliceinttostring
,
no
race
because
strings
are
immutable
.
p
=
s
.
str
;
ep
=
s
.
str
+
s
.
len
;
n
=
0
;
while
(
p
<
ep
)
{
p
+=
charntorune
(&
dum
,
p
,
ep
-
p
);
n
++;
}
b
.
array
=
mallocgc
(
n
*
sizeof
(
r
[
0
]),
RefNoPointers
,
1
,
1
);
b
.
len
=
n
;
b
.
cap
=
n
;
p
=
s
.
str
;
r
=
(
int32
*)
b
.
array
;
while
(
p
<
ep
)
p
+=
charntorune
(
r
++,
p
,
ep
-
p
);
}
enum
enum
{
{
Runeself
=
0x80
,
Runeself
=
0x80
,
...
...
test/convlit.go
View file @
39101613
...
@@ -35,3 +35,30 @@ var good2 int = 1.0;
...
@@ -35,3 +35,30 @@ var good2 int = 1.0;
var
good3
int
=
1e9
;
var
good3
int
=
1e9
;
var
good4
float
=
1e20
;
var
good4
float
=
1e20
;
// explicit conversion of string is okay
var
_
=
[]
int
(
"abc"
)
var
_
=
[]
byte
(
"abc"
)
// implicit is not
var
_
[]
int
=
"abc"
// ERROR "cannot use|incompatible|invalid"
var
_
[]
byte
=
"abc"
// ERROR "cannot use|incompatible|invalid"
// named string is okay
type
Tstring
string
var
ss
Tstring
=
"abc"
var
_
=
[]
int
(
ss
)
var
_
=
[]
byte
(
ss
)
// implicit is still not
var
_
[]
int
=
ss
// ERROR "cannot use|incompatible|invalid"
var
_
[]
byte
=
ss
// ERROR "cannot use|incompatible|invalid"
// named slice is not
type
Tint
[]
int
type
Tbyte
[]
byte
var
_
=
Tint
(
"abc"
)
// ERROR "convert|incompatible|invalid"
var
_
=
Tbyte
(
"abc"
)
// ERROR "convert|incompatible|invalid"
// implicit is still not
var
_
Tint
=
"abc"
// ERROR "cannot use|incompatible|invalid"
var
_
Tbyte
=
"abc"
// ERROR "cannot use|incompatible|invalid"
test/string_lit.go
View file @
39101613
...
@@ -34,6 +34,19 @@ func assert(a, b, c string) {
...
@@ -34,6 +34,19 @@ func assert(a, b, c string) {
}
}
}
}
const
(
gx1
=
"aä本☺"
gx2
=
"aä
\xFF\xFF
本☺"
gx2fix
=
"aä
\uFFFD\uFFFD
本☺"
)
var
(
gr1
=
[]
int
(
gx1
)
gr2
=
[]
int
(
gx2
)
gb1
=
[]
byte
(
gx1
)
gb2
=
[]
byte
(
gx2
)
)
func
main
()
{
func
main
()
{
ecode
=
0
;
ecode
=
0
;
s
:=
s
:=
...
@@ -86,5 +99,22 @@ func main() {
...
@@ -86,5 +99,22 @@ func main() {
r
=
0x10ffff
+
1
;
r
=
0x10ffff
+
1
;
s
=
string
(
r
);
s
=
string
(
r
);
assert
(
s
,
"
\xef\xbf\xbd
"
,
"too-large rune"
);
assert
(
s
,
"
\xef\xbf\xbd
"
,
"too-large rune"
);
assert
(
string
(
gr1
),
gx1
,
"global ->[]int"
)
assert
(
string
(
gr2
),
gx2fix
,
"global invalid ->[]int"
)
assert
(
string
(
gb1
),
gx1
,
"->[]byte"
)
assert
(
string
(
gb2
),
gx2
,
"global invalid ->[]byte"
)
var
(
r1
=
[]
int
(
gx1
)
r2
=
[]
int
(
gx2
)
b1
=
[]
byte
(
gx1
)
b2
=
[]
byte
(
gx2
)
)
assert
(
string
(
r1
),
gx1
,
"->[]int"
)
assert
(
string
(
r2
),
gx2fix
,
"invalid ->[]int"
)
assert
(
string
(
b1
),
gx1
,
"->[]byte"
)
assert
(
string
(
b2
),
gx2
,
"invalid ->[]byte"
)
os
.
Exit
(
ecode
);
os
.
Exit
(
ecode
);
}
}
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