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
d8c19c80
Commit
d8c19c80
authored
Aug 04, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
type checking of assignments, switch, if, for
R=ken OCL=32716 CL=32720
parent
417683c3
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
411 additions
and
643 deletions
+411
-643
src/cmd/gc/const.c
src/cmd/gc/const.c
+12
-1
src/cmd/gc/go.h
src/cmd/gc/go.h
+2
-21
src/cmd/gc/print.c
src/cmd/gc/print.c
+1
-0
src/cmd/gc/swt.c
src/cmd/gc/swt.c
+62
-121
src/cmd/gc/typecheck.c
src/cmd/gc/typecheck.c
+236
-133
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+98
-367
No files found.
src/cmd/gc/const.c
View file @
d8c19c80
...
@@ -704,6 +704,7 @@ nodlit(Val v)
...
@@ -704,6 +704,7 @@ nodlit(Val v)
return
n
;
return
n
;
}
}
// TODO(rsc): combine with convlit
void
void
defaultlit
(
Node
**
np
,
Type
*
t
)
defaultlit
(
Node
**
np
,
Type
*
t
)
{
{
...
@@ -713,7 +714,7 @@ defaultlit(Node **np, Type *t)
...
@@ -713,7 +714,7 @@ defaultlit(Node **np, Type *t)
n
=
*
np
;
n
=
*
np
;
if
(
n
==
N
)
if
(
n
==
N
)
return
;
return
;
if
(
n
->
type
==
T
||
n
->
type
->
etype
!=
TIDEAL
)
if
(
n
->
type
==
T
||
(
n
->
type
->
etype
!=
TIDEAL
&&
n
->
type
->
etype
!=
TNIL
)
)
return
;
return
;
switch
(
n
->
op
)
{
switch
(
n
->
op
)
{
...
@@ -739,6 +740,16 @@ defaultlit(Node **np, Type *t)
...
@@ -739,6 +740,16 @@ defaultlit(Node **np, Type *t)
lineno
=
n
->
lineno
;
lineno
=
n
->
lineno
;
switch
(
n
->
val
.
ctype
)
{
switch
(
n
->
val
.
ctype
)
{
default:
default:
if
(
t
!=
T
)
{
convlit
(
np
,
t
);
break
;
}
if
(
n
->
val
.
ctype
==
CTNIL
)
{
lineno
=
lno
;
yyerror
(
"use of untyped nil"
);
n
->
type
=
T
;
break
;
}
yyerror
(
"defaultlit: unknown literal: %#N"
,
n
);
yyerror
(
"defaultlit: unknown literal: %#N"
,
n
);
break
;
break
;
case
CTINT
:
case
CTINT
:
...
...
src/cmd/gc/go.h
View file @
d8c19c80
...
@@ -334,7 +334,7 @@ enum
...
@@ -334,7 +334,7 @@ enum
OAPPENDSTR
,
OAPPENDSTR
,
OARRAY
,
OARRAY
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OAS
,
OAS2
,
OASOP
,
OAS
,
OAS2
,
OAS
2MAPW
,
OAS2FUNC
,
OAS2RECV
,
OAS2MAPR
,
OAS2DOTTYPE
,
OAS
OP
,
OBAD
,
OBAD
,
OCALL
,
OCALLFUNC
,
OCALLMETH
,
OCALLINTER
,
OCALL
,
OCALLFUNC
,
OCALLMETH
,
OCALLINTER
,
OCAP
,
OCAP
,
...
@@ -952,18 +952,6 @@ void dumpexport(void);
...
@@ -952,18 +952,6 @@ void dumpexport(void);
void
dumpexporttype
(
Sym
*
);
void
dumpexporttype
(
Sym
*
);
void
dumpexportvar
(
Sym
*
);
void
dumpexportvar
(
Sym
*
);
void
dumpexportconst
(
Sym
*
);
void
dumpexportconst
(
Sym
*
);
void
doimportv1
(
Node
*
,
Node
*
);
void
doimportc1
(
Node
*
,
Val
*
);
void
doimportc2
(
Node
*
,
Node
*
,
Val
*
);
void
doimport1
(
Node
*
,
Node
*
,
Node
*
);
void
doimport2
(
Node
*
,
Val
*
,
Node
*
);
void
doimport3
(
Node
*
,
Node
*
);
void
doimport4
(
Node
*
,
Node
*
);
void
doimport5
(
Node
*
,
Val
*
);
void
doimport6
(
Node
*
,
Node
*
);
void
doimport7
(
Node
*
,
Node
*
);
void
doimport8
(
Node
*
,
Val
*
,
Node
*
);
void
doimport9
(
Sym
*
,
Node
*
);
void
importconst
(
Sym
*
s
,
Type
*
t
,
Node
*
v
);
void
importconst
(
Sym
*
s
,
Type
*
t
,
Node
*
v
);
void
importmethod
(
Sym
*
s
,
Type
*
t
);
void
importmethod
(
Sym
*
s
,
Type
*
t
);
void
importtype
(
Sym
*
s
,
Type
*
t
);
void
importtype
(
Sym
*
s
,
Type
*
t
);
...
@@ -981,7 +969,6 @@ void walkexprlist(NodeList*, NodeList**);
...
@@ -981,7 +969,6 @@ void walkexprlist(NodeList*, NodeList**);
void
walkconv
(
Node
**
,
NodeList
**
);
void
walkconv
(
Node
**
,
NodeList
**
);
void
walkdottype
(
Node
*
,
NodeList
**
);
void
walkdottype
(
Node
*
,
NodeList
**
);
void
walkas
(
Node
*
);
void
walkas
(
Node
*
);
void
walkbool
(
Node
**
);
void
walkswitch
(
Node
*
);
void
walkswitch
(
Node
*
);
void
walkselect
(
Node
*
);
void
walkselect
(
Node
*
);
void
walkdot
(
Node
*
,
NodeList
**
);
void
walkdot
(
Node
*
,
NodeList
**
);
...
@@ -990,21 +977,14 @@ Node* ascompatee1(int, Node*, Node*, NodeList**);
...
@@ -990,21 +977,14 @@ Node* ascompatee1(int, Node*, Node*, NodeList**);
NodeList
*
ascompatee
(
int
,
NodeList
*
,
NodeList
*
,
NodeList
**
);
NodeList
*
ascompatee
(
int
,
NodeList
*
,
NodeList
*
,
NodeList
**
);
NodeList
*
ascompatet
(
int
,
NodeList
*
,
Type
**
,
int
,
NodeList
**
);
NodeList
*
ascompatet
(
int
,
NodeList
*
,
Type
**
,
int
,
NodeList
**
);
NodeList
*
ascompatte
(
int
,
Type
**
,
NodeList
*
,
int
,
NodeList
**
);
NodeList
*
ascompatte
(
int
,
Type
**
,
NodeList
*
,
int
,
NodeList
**
);
int
ascompat
(
Type
*
,
Type
*
);
Node
*
newcompat
(
Node
*
);
Node
*
stringop
(
Node
*
,
NodeList
**
);
Type
*
fixmap
(
Type
*
);
Node
*
mapop
(
Node
*
,
NodeList
**
);
Node
*
mapop
(
Node
*
,
NodeList
**
);
Type
*
fixchan
(
Type
*
);
Type
*
fixchan
(
Type
*
);
Node
*
chanop
(
Node
*
,
NodeList
**
);
Node
*
ifacecvt
(
Type
*
,
Node
*
,
int
,
NodeList
**
);
Node
*
ifacecvt
(
Type
*
,
Node
*
,
int
,
NodeList
**
);
Node
*
ifaceop
(
Node
*
);
int
ifaceas
(
Type
*
,
Type
*
,
int
);
int
ifaceas
(
Type
*
,
Type
*
,
int
);
int
ifaceas1
(
Type
*
,
Type
*
,
int
);
int
ifaceas1
(
Type
*
,
Type
*
,
int
);
void
ifacecheck
(
Type
*
,
Type
*
,
int
,
int
);
void
ifacecheck
(
Type
*
,
Type
*
,
int
,
int
);
void
runifacechecks
(
void
);
void
runifacechecks
(
void
);
Node
*
convas
(
Node
*
,
NodeList
**
);
Node
*
convas
(
Node
*
,
NodeList
**
);
void
arrayconv
(
Type
*
,
Node
*
);
Node
*
colas
(
NodeList
*
,
NodeList
*
);
Node
*
colas
(
NodeList
*
,
NodeList
*
);
Node
*
dorange
(
Node
*
);
Node
*
dorange
(
Node
*
);
NodeList
*
reorder1
(
NodeList
*
);
NodeList
*
reorder1
(
NodeList
*
);
...
@@ -1019,6 +999,7 @@ void heapmoves(void);
...
@@ -1019,6 +999,7 @@ void heapmoves(void);
void
walkdeflist
(
NodeList
*
);
void
walkdeflist
(
NodeList
*
);
void
walkdef
(
Node
*
);
void
walkdef
(
Node
*
);
void
typechecklist
(
NodeList
*
,
int
);
void
typechecklist
(
NodeList
*
,
int
);
void
typecheckswitch
(
Node
*
);
Node
*
typecheckconv
(
Node
*
,
Node
*
,
Type
*
,
int
);
Node
*
typecheckconv
(
Node
*
,
Node
*
,
Type
*
,
int
);
Node
*
typecheck
(
Node
**
,
int
);
Node
*
typecheck
(
Node
**
,
int
);
...
...
src/cmd/gc/print.c
View file @
d8c19c80
...
@@ -231,6 +231,7 @@ exprfmt(Fmt *f, Node *n, int prec)
...
@@ -231,6 +231,7 @@ exprfmt(Fmt *f, Node *n, int prec)
break
;
break
;
case
OINDEX
:
case
OINDEX
:
case
OINDEXMAP
:
exprfmt
(
f
,
n
->
left
,
7
);
exprfmt
(
f
,
n
->
left
,
7
);
fmtprint
(
f
,
"["
);
fmtprint
(
f
,
"["
);
exprfmt
(
f
,
n
->
right
,
0
);
exprfmt
(
f
,
n
->
right
,
0
);
...
...
src/cmd/gc/swt.c
View file @
d8c19c80
...
@@ -233,112 +233,6 @@ csort(Case *l, int(*f)(Case*, Case*))
...
@@ -233,112 +233,6 @@ csort(Case *l, int(*f)(Case*, Case*))
return
l
;
return
l
;
}
}
/*
* walktype
*/
Type
*
sw0
(
Node
**
cp
,
Type
*
place
,
int
arg
)
{
Node
*
c
;
c
=
*
cp
;
if
(
c
==
N
)
return
T
;
switch
(
c
->
op
)
{
default:
if
(
arg
==
Stype
)
{
yyerror
(
"expression case in a type switch"
);
return
T
;
}
walkexpr
(
cp
,
nil
);
break
;
case
OTYPESW
:
case
OTYPECASE
:
if
(
arg
!=
Stype
)
yyerror
(
"type case in an expression switch"
);
break
;
case
OAS
:
yyerror
(
"inappropriate assignment in a case statement"
);
break
;
}
return
T
;
}
/*
* return the first type
*/
Type
*
sw1
(
Node
**
cp
,
Type
*
place
,
int
arg
)
{
Node
*
c
;
c
=
*
cp
;
if
(
place
!=
T
)
return
notideal
(
c
->
type
);
return
place
;
}
/*
* return a suitable type
*/
Type
*
sw2
(
Node
**
cp
,
Type
*
place
,
int
arg
)
{
return
types
[
TINT
];
// botch
}
/*
* check that switch type
* is compat with all the cases
*/
Type
*
sw3
(
Node
**
cp
,
Type
*
place
,
int
arg
)
{
Node
*
c
;
c
=
*
cp
;
if
(
place
==
T
)
return
c
->
type
;
if
(
c
->
type
==
T
)
c
->
type
=
place
;
convlit
(
cp
,
place
);
c
=
*
cp
;
if
(
!
ascompat
(
place
,
c
->
type
))
badtype
(
OSWITCH
,
place
,
c
->
type
);
return
place
;
}
/*
* over all cases, call parameter function.
* four passes of these are used to allocate
* types to cases and switch
*/
Type
*
walkcases
(
Node
*
sw
,
Type
*
(
*
call
)(
Node
**
,
Type
*
,
int
arg
),
int
arg
)
{
Node
*
n
;
NodeList
*
l
;
Type
*
place
;
int32
lno
;
lno
=
setlineno
(
sw
);
place
=
call
(
&
sw
->
ntest
,
T
,
arg
);
for
(
l
=
sw
->
list
;
l
;
l
=
l
->
next
)
{
n
=
l
->
n
;
if
(
n
->
op
!=
OCASE
)
fatal
(
"walkcases: not case %O
\n
"
,
n
->
op
);
if
(
n
->
left
!=
N
&&
!
n
->
diag
)
{
setlineno
(
n
);
place
=
call
(
&
n
->
left
,
place
,
arg
);
}
}
lineno
=
lno
;
return
place
;
}
Node
*
Node
*
newlabel
(
void
)
newlabel
(
void
)
{
{
...
@@ -597,22 +491,9 @@ exprswitch(Node *sw)
...
@@ -597,22 +491,9 @@ exprswitch(Node *sw)
arg
=
Sfalse
;
arg
=
Sfalse
;
}
}
walkexpr
(
&
sw
->
ntest
,
&
sw
->
ninit
);
walkexpr
(
&
sw
->
ntest
,
&
sw
->
ninit
);
t
=
sw
->
type
;
/*
* pass 0,1,2,3
* walk the cases as appropriate for switch type
*/
walkcases
(
sw
,
sw0
,
arg
);
t
=
notideal
(
sw
->
ntest
->
type
);
if
(
t
==
T
)
t
=
walkcases
(
sw
,
sw1
,
arg
);
if
(
t
==
T
)
t
=
walkcases
(
sw
,
sw2
,
arg
);
if
(
t
==
T
)
if
(
t
==
T
)
return
;
return
;
walkcases
(
sw
,
sw3
,
arg
);
convlit
(
&
sw
->
ntest
,
t
);
/*
/*
* convert the switch into OIF statements
* convert the switch into OIF statements
...
@@ -785,7 +666,6 @@ typeswitch(Node *sw)
...
@@ -785,7 +666,6 @@ typeswitch(Node *sw)
yyerror
(
"type switch must be on an interface"
);
yyerror
(
"type switch must be on an interface"
);
return
;
return
;
}
}
walkcases
(
sw
,
sw0
,
Stype
);
cas
=
nil
;
cas
=
nil
;
/*
/*
...
@@ -886,3 +766,64 @@ walkswitch(Node *sw)
...
@@ -886,3 +766,64 @@ walkswitch(Node *sw)
}
}
exprswitch
(
sw
);
exprswitch
(
sw
);
}
}
/*
* type check switch statement
*/
void
typecheckswitch
(
Node
*
n
)
{
int
top
,
lno
;
Type
*
t
;
NodeList
*
l
,
*
ll
;
Node
*
ncase
;
Node
*
def
;
lno
=
lineno
;
typechecklist
(
n
->
ninit
,
Etop
);
if
(
n
->
ntest
!=
N
&&
n
->
ntest
->
op
==
OTYPESW
)
{
// type switch
typecheck
(
&
n
->
ntest
,
Etop
);
top
=
Etype
;
t
=
n
->
ntest
->
type
;
if
(
t
!=
T
&&
t
->
etype
!=
TINTER
)
yyerror
(
"cannot type switch on non-interface value %+N"
,
n
->
ntest
);
}
else
{
// value switch
top
=
Erv
;
if
(
n
->
ntest
)
{
typecheck
(
&
n
->
ntest
,
Erv
);
defaultlit
(
&
n
->
ntest
,
T
);
t
=
n
->
ntest
->
type
;
}
else
t
=
types
[
TBOOL
];
}
n
->
type
=
t
;
def
=
N
;
for
(
l
=
n
->
list
;
l
;
l
=
l
->
next
)
{
ncase
=
l
->
n
;
setlineno
(
n
);
if
(
ncase
->
list
==
nil
)
{
// default
if
(
def
!=
N
)
yyerror
(
"multiple defaults in switch (first at %L)"
,
def
->
lineno
);
else
def
=
ncase
;
}
else
{
for
(
ll
=
ncase
->
list
;
ll
;
ll
=
ll
->
next
)
{
setlineno
(
ll
->
n
);
typecheck
(
&
ll
->
n
,
Erv
);
// TODO(rsc): top
if
(
ll
->
n
->
type
==
T
||
t
==
T
||
top
!=
Erv
)
continue
;
defaultlit
(
&
ll
->
n
,
t
);
if
(
ll
->
n
->
type
!=
T
&&
!
eqtype
(
ll
->
n
->
type
,
t
))
yyerror
(
"case %+N in switch of %+N %#O"
,
ll
->
n
,
n
->
ntest
,
ll
->
n
->
op
);
}
}
typechecklist
(
ncase
->
nbody
,
Etop
);
}
lineno
=
lno
;
}
src/cmd/gc/typecheck.c
View file @
d8c19c80
This diff is collapsed.
Click to expand it.
src/cmd/gc/walk.c
View file @
d8c19c80
This diff is collapsed.
Click to expand it.
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