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
bed6238c
Commit
bed6238c
authored
Oct 03, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Fix a, b, c := b, a, 1 when a and b already exist.
From-SVN: r192022
parent
e1d90a81
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
60 additions
and
16 deletions
+60
-16
gcc/go/gofrontend/parse.cc
+56
-15
gcc/go/gofrontend/parse.h
+4
-1
No files found.
gcc/go/gofrontend/parse.cc
View file @
bed6238c
...
...
@@ -1631,12 +1631,16 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
// Note that INIT was already parsed with the old name bindings, so
// we don't have to worry that it will accidentally refer to the
// newly declared variables.
// newly declared variables. But we do have to worry about a mix of
// newly declared variables and old variables if the old variables
// appear in the initializations.
Expression_list
::
const_iterator
pexpr
;
if
(
init
!=
NULL
)
pexpr
=
init
->
begin
();
bool
any_new
=
false
;
Expression_list
*
vars
=
new
Expression_list
();
Expression_list
*
vals
=
new
Expression_list
();
for
(
Typed_identifier_list
::
const_iterator
p
=
til
->
begin
();
p
!=
til
->
end
();
++
p
)
...
...
@@ -1644,7 +1648,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
if
(
init
!=
NULL
)
go_assert
(
pexpr
!=
init
->
end
());
this
->
init_var
(
*
p
,
type
,
init
==
NULL
?
NULL
:
*
pexpr
,
is_coloneq
,
false
,
&
any_new
);
false
,
&
any_new
,
vars
,
vals
);
if
(
init
!=
NULL
)
++
pexpr
;
}
...
...
@@ -1652,6 +1656,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
go_assert
(
pexpr
==
init
->
end
());
if
(
is_coloneq
&&
!
any_new
)
error_at
(
location
,
"variables redeclared but no variable is new"
);
this
->
finish_init_vars
(
vars
,
vals
,
location
);
}
// See if we need to initialize a list of variables from a function
...
...
@@ -1674,13 +1679,15 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
Named_object
*
first_var
=
NULL
;
unsigned
int
index
=
0
;
bool
any_new
=
false
;
Expression_list
*
ivars
=
new
Expression_list
();
Expression_list
*
ivals
=
new
Expression_list
();
for
(
Typed_identifier_list
::
const_iterator
pv
=
vars
->
begin
();
pv
!=
vars
->
end
();
++
pv
,
++
index
)
{
Expression
*
init
=
Expression
::
make_call_result
(
call
,
index
);
Named_object
*
no
=
this
->
init_var
(
*
pv
,
type
,
init
,
is_coloneq
,
false
,
&
any_new
);
&
any_new
,
ivars
,
ivals
);
if
(
this
->
gogo_
->
in_global_scope
()
&&
no
->
is_variable
())
{
...
...
@@ -1700,6 +1707,8 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
if
(
is_coloneq
&&
!
any_new
)
error_at
(
location
,
"variables redeclared but no variable is new"
);
this
->
finish_init_vars
(
ivars
,
ivals
,
location
);
return
true
;
}
...
...
@@ -1725,7 +1734,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
Typed_identifier_list
::
const_iterator
p
=
vars
->
begin
();
Expression
*
init
=
type
==
NULL
?
index
:
NULL
;
Named_object
*
val_no
=
this
->
init_var
(
*
p
,
type
,
init
,
is_coloneq
,
type
==
NULL
,
&
any_new
);
type
==
NULL
,
&
any_new
,
NULL
,
NULL
);
if
(
type
==
NULL
&&
any_new
&&
val_no
->
is_variable
())
val_no
->
var_value
()
->
set_type_from_init_tuple
();
Expression
*
val_var
=
Expression
::
make_var_reference
(
val_no
,
location
);
...
...
@@ -1735,7 +1744,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
if
(
var_type
==
NULL
)
var_type
=
Type
::
lookup_bool_type
();
Named_object
*
no
=
this
->
init_var
(
*
p
,
var_type
,
NULL
,
is_coloneq
,
false
,
&
any_new
);
&
any_new
,
NULL
,
NULL
);
Expression
*
present_var
=
Expression
::
make_var_reference
(
no
,
location
);
if
(
is_coloneq
&&
!
any_new
)
...
...
@@ -1790,7 +1799,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
Typed_identifier_list
::
const_iterator
p
=
vars
->
begin
();
Expression
*
init
=
type
==
NULL
?
receive
:
NULL
;
Named_object
*
val_no
=
this
->
init_var
(
*
p
,
type
,
init
,
is_coloneq
,
type
==
NULL
,
&
any_new
);
type
==
NULL
,
&
any_new
,
NULL
,
NULL
);
if
(
type
==
NULL
&&
any_new
&&
val_no
->
is_variable
())
val_no
->
var_value
()
->
set_type_from_init_tuple
();
Expression
*
val_var
=
Expression
::
make_var_reference
(
val_no
,
location
);
...
...
@@ -1800,7 +1809,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
if
(
var_type
==
NULL
)
var_type
=
Type
::
lookup_bool_type
();
Named_object
*
no
=
this
->
init_var
(
*
p
,
var_type
,
NULL
,
is_coloneq
,
false
,
&
any_new
);
&
any_new
,
NULL
,
NULL
);
Expression
*
received_var
=
Expression
::
make_var_reference
(
no
,
location
);
if
(
is_coloneq
&&
!
any_new
)
...
...
@@ -1857,7 +1866,7 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
if
(
var_type
==
NULL
)
var_type
=
type_guard
->
type
();
Named_object
*
val_no
=
this
->
init_var
(
*
p
,
var_type
,
NULL
,
is_coloneq
,
false
,
&
any_new
);
&
any_new
,
NULL
,
NULL
);
Expression
*
val_var
=
Expression
::
make_var_reference
(
val_no
,
location
);
++
p
;
...
...
@@ -1865,7 +1874,7 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
if
(
var_type
==
NULL
)
var_type
=
Type
::
lookup_bool_type
();
Named_object
*
no
=
this
->
init_var
(
*
p
,
var_type
,
NULL
,
is_coloneq
,
false
,
&
any_new
);
&
any_new
,
NULL
,
NULL
);
Expression
*
ok_var
=
Expression
::
make_var_reference
(
no
,
location
);
Expression
*
texpr
=
type_guard
->
expr
();
...
...
@@ -1904,7 +1913,8 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
Named_object
*
Parse
::
init_var
(
const
Typed_identifier
&
tid
,
Type
*
type
,
Expression
*
init
,
bool
is_coloneq
,
bool
type_from_init
,
bool
*
is_new
)
bool
is_coloneq
,
bool
type_from_init
,
bool
*
is_new
,
Expression_list
*
vars
,
Expression_list
*
vals
)
{
Location
location
=
tid
.
location
();
...
...
@@ -1946,9 +1956,9 @@ Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
// like v, ok := x.(int).
if
(
!
type_from_init
&&
init
!=
NULL
)
{
Expression
*
v
=
Expression
::
make_var_reference
(
no
,
location
);
Statement
*
s
=
Statement
::
make_assignment
(
v
,
init
,
location
);
this
->
gogo_
->
add_statement
(
s
);
go_assert
(
vars
!=
NULL
&&
vals
!=
NULL
);
vars
->
push_back
(
Expression
::
make_var_reference
(
no
,
location
)
);
vals
->
push_back
(
init
);
}
return
no
;
}
...
...
@@ -1983,6 +1993,36 @@ Parse::create_dummy_global(Type* type, Expression* init,
return
this
->
gogo_
->
add_variable
(
buf
,
var
);
}
// Finish the variable initialization by executing any assignments to
// existing variables when using :=. These must be done as a tuple
// assignment in case of something like n, a, b := 1, b, a.
void
Parse
::
finish_init_vars
(
Expression_list
*
vars
,
Expression_list
*
vals
,
Location
location
)
{
if
(
vars
->
empty
())
{
delete
vars
;
delete
vals
;
}
else
if
(
vars
->
size
()
==
1
)
{
go_assert
(
!
this
->
gogo_
->
in_global_scope
());
this
->
gogo_
->
add_statement
(
Statement
::
make_assignment
(
vars
->
front
(),
vals
->
front
(),
location
));
delete
vars
;
delete
vals
;
}
else
{
go_assert
(
!
this
->
gogo_
->
in_global_scope
());
this
->
gogo_
->
add_statement
(
Statement
::
make_tuple_assignment
(
vars
,
vals
,
location
));
}
}
// SimpleVarDecl = identifier ":=" Expression .
// We've already seen the identifier.
...
...
@@ -5113,7 +5153,8 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
bool
any_new
=
false
;
const
Typed_identifier
*
pti
=
&
til
->
front
();
Named_object
*
no
=
this
->
init_var
(
*
pti
,
NULL
,
expr
,
true
,
true
,
&
any_new
);
Named_object
*
no
=
this
->
init_var
(
*
pti
,
NULL
,
expr
,
true
,
true
,
&
any_new
,
NULL
,
NULL
);
if
(
any_new
&&
no
->
is_variable
())
no
->
var_value
()
->
set_type_from_range_index
();
p_range_clause
->
index
=
Expression
::
make_var_reference
(
no
,
location
);
...
...
@@ -5124,7 +5165,7 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
{
pti
=
&
til
->
back
();
bool
is_new
=
false
;
no
=
this
->
init_var
(
*
pti
,
NULL
,
expr
,
true
,
true
,
&
is_new
);
no
=
this
->
init_var
(
*
pti
,
NULL
,
expr
,
true
,
true
,
&
is_new
,
NULL
,
NULL
);
if
(
is_new
&&
no
->
is_variable
())
no
->
var_value
()
->
set_type_from_range_value
();
if
(
is_new
)
...
...
gcc/go/gofrontend/parse.h
View file @
bed6238c
...
...
@@ -206,8 +206,11 @@ class Parse
Expression
*
,
bool
is_coloneq
,
Location
);
Named_object
*
init_var
(
const
Typed_identifier
&
,
Type
*
,
Expression
*
,
bool
is_coloneq
,
bool
type_from_init
,
bool
*
is_new
);
bool
is_coloneq
,
bool
type_from_init
,
bool
*
is_new
,
Expression_list
*
vars
,
Expression_list
*
vals
);
Named_object
*
create_dummy_global
(
Type
*
,
Expression
*
,
Location
);
void
finish_init_vars
(
Expression_list
*
vars
,
Expression_list
*
vals
,
Location
);
void
simple_var_decl_or_assignment
(
const
std
::
string
&
,
Location
,
bool
may_be_composite_lit
,
Range_clause
*
,
Type_switch
*
);
...
...
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