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
280deda6
Commit
280deda6
authored
Sep 13, 2011
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix inherited hidden methods that return hidden types.
From-SVN: r178818
parent
bd1aa4f4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
94 additions
and
13 deletions
+94
-13
gcc/go/gofrontend/statements.cc
+65
-9
gcc/go/gofrontend/statements.h
+22
-3
gcc/go/gofrontend/types.cc
+7
-1
No files found.
gcc/go/gofrontend/statements.cc
View file @
280deda6
...
@@ -402,7 +402,13 @@ Temporary_statement::do_check_types(Gogo*)
...
@@ -402,7 +402,13 @@ Temporary_statement::do_check_types(Gogo*)
if
(
this
->
type_
!=
NULL
&&
this
->
init_
!=
NULL
)
if
(
this
->
type_
!=
NULL
&&
this
->
init_
!=
NULL
)
{
{
std
::
string
reason
;
std
::
string
reason
;
if
(
!
Type
::
are_assignable
(
this
->
type_
,
this
->
init_
->
type
(),
&
reason
))
bool
ok
;
if
(
this
->
are_hidden_fields_ok_
)
ok
=
Type
::
are_assignable_hidden_ok
(
this
->
type_
,
this
->
init_
->
type
(),
&
reason
);
else
ok
=
Type
::
are_assignable
(
this
->
type_
,
this
->
init_
->
type
(),
&
reason
);
if
(
!
ok
)
{
{
if
(
reason
.
empty
())
if
(
reason
.
empty
())
error_at
(
this
->
location
(),
"incompatible types in assignment"
);
error_at
(
this
->
location
(),
"incompatible types in assignment"
);
...
@@ -504,9 +510,15 @@ class Assignment_statement : public Statement
...
@@ -504,9 +510,15 @@ class Assignment_statement : public Statement
Assignment_statement
(
Expression
*
lhs
,
Expression
*
rhs
,
Assignment_statement
(
Expression
*
lhs
,
Expression
*
rhs
,
source_location
location
)
source_location
location
)
:
Statement
(
STATEMENT_ASSIGNMENT
,
location
),
:
Statement
(
STATEMENT_ASSIGNMENT
,
location
),
lhs_
(
lhs
),
rhs_
(
rhs
)
lhs_
(
lhs
),
rhs_
(
rhs
)
,
are_hidden_fields_ok_
(
false
)
{
}
{
}
// Note that it is OK for this assignment statement to set hidden
// fields.
void
set_hidden_fields_are_ok
()
{
this
->
are_hidden_fields_ok_
=
true
;
}
protected
:
protected
:
int
int
do_traverse
(
Traverse
*
traverse
);
do_traverse
(
Traverse
*
traverse
);
...
@@ -531,6 +543,9 @@ class Assignment_statement : public Statement
...
@@ -531,6 +543,9 @@ class Assignment_statement : public Statement
Expression
*
lhs_
;
Expression
*
lhs_
;
// Right hand side--the rvalue.
// Right hand side--the rvalue.
Expression
*
rhs_
;
Expression
*
rhs_
;
// True if this statement may set hidden fields in the assignment
// statement. This is used for generated method stubs.
bool
are_hidden_fields_ok_
;
};
};
// Traversal.
// Traversal.
...
@@ -579,7 +594,12 @@ Assignment_statement::do_check_types(Gogo*)
...
@@ -579,7 +594,12 @@ Assignment_statement::do_check_types(Gogo*)
Type
*
lhs_type
=
this
->
lhs_
->
type
();
Type
*
lhs_type
=
this
->
lhs_
->
type
();
Type
*
rhs_type
=
this
->
rhs_
->
type
();
Type
*
rhs_type
=
this
->
rhs_
->
type
();
std
::
string
reason
;
std
::
string
reason
;
if
(
!
Type
::
are_assignable
(
lhs_type
,
rhs_type
,
&
reason
))
bool
ok
;
if
(
this
->
are_hidden_fields_ok_
)
ok
=
Type
::
are_assignable_hidden_ok
(
lhs_type
,
rhs_type
,
&
reason
);
else
ok
=
Type
::
are_assignable
(
lhs_type
,
rhs_type
,
&
reason
);
if
(
!
ok
)
{
{
if
(
reason
.
empty
())
if
(
reason
.
empty
())
error_at
(
this
->
location
(),
"incompatible types in assignment"
);
error_at
(
this
->
location
(),
"incompatible types in assignment"
);
...
@@ -820,9 +840,15 @@ class Tuple_assignment_statement : public Statement
...
@@ -820,9 +840,15 @@ class Tuple_assignment_statement : public Statement
Tuple_assignment_statement
(
Expression_list
*
lhs
,
Expression_list
*
rhs
,
Tuple_assignment_statement
(
Expression_list
*
lhs
,
Expression_list
*
rhs
,
source_location
location
)
source_location
location
)
:
Statement
(
STATEMENT_TUPLE_ASSIGNMENT
,
location
),
:
Statement
(
STATEMENT_TUPLE_ASSIGNMENT
,
location
),
lhs_
(
lhs
),
rhs_
(
rhs
)
lhs_
(
lhs
),
rhs_
(
rhs
)
,
are_hidden_fields_ok_
(
false
)
{
}
{
}
// Note that it is OK for this assignment statement to set hidden
// fields.
void
set_hidden_fields_are_ok
()
{
this
->
are_hidden_fields_ok_
=
true
;
}
protected
:
protected
:
int
int
do_traverse
(
Traverse
*
traverse
);
do_traverse
(
Traverse
*
traverse
);
...
@@ -846,6 +872,9 @@ class Tuple_assignment_statement : public Statement
...
@@ -846,6 +872,9 @@ class Tuple_assignment_statement : public Statement
Expression_list
*
lhs_
;
Expression_list
*
lhs_
;
// Right hand side--a list of rvalues.
// Right hand side--a list of rvalues.
Expression_list
*
rhs_
;
Expression_list
*
rhs_
;
// True if this statement may set hidden fields in the assignment
// statement. This is used for generated method stubs.
bool
are_hidden_fields_ok_
;
};
};
// Traversal.
// Traversal.
...
@@ -901,6 +930,8 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
...
@@ -901,6 +930,8 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Temporary_statement
*
temp
=
Statement
::
make_temporary
((
*
plhs
)
->
type
(),
Temporary_statement
*
temp
=
Statement
::
make_temporary
((
*
plhs
)
->
type
(),
*
prhs
,
loc
);
*
prhs
,
loc
);
if
(
this
->
are_hidden_fields_ok_
)
temp
->
set_hidden_fields_are_ok
();
b
->
add_statement
(
temp
);
b
->
add_statement
(
temp
);
temps
.
push_back
(
temp
);
temps
.
push_back
(
temp
);
...
@@ -924,6 +955,11 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
...
@@ -924,6 +955,11 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
Expression
*
ref
=
Expression
::
make_temporary_reference
(
*
ptemp
,
loc
);
Expression
*
ref
=
Expression
::
make_temporary_reference
(
*
ptemp
,
loc
);
Statement
*
s
=
Statement
::
make_assignment
(
*
plhs
,
ref
,
loc
);
Statement
*
s
=
Statement
::
make_assignment
(
*
plhs
,
ref
,
loc
);
if
(
this
->
are_hidden_fields_ok_
)
{
Assignment_statement
*
as
=
static_cast
<
Assignment_statement
*>
(
s
);
as
->
set_hidden_fields_are_ok
();
}
b
->
add_statement
(
s
);
b
->
add_statement
(
s
);
++
ptemp
;
++
ptemp
;
}
}
...
@@ -2592,7 +2628,12 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
...
@@ -2592,7 +2628,12 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
e
->
determine_type
(
&
type_context
);
e
->
determine_type
(
&
type_context
);
std
::
string
reason
;
std
::
string
reason
;
if
(
Type
::
are_assignable
(
rvtype
,
e
->
type
(),
&
reason
))
bool
ok
;
if
(
this
->
are_hidden_fields_ok_
)
ok
=
Type
::
are_assignable_hidden_ok
(
rvtype
,
e
->
type
(),
&
reason
);
else
ok
=
Type
::
are_assignable
(
rvtype
,
e
->
type
(),
&
reason
);
if
(
ok
)
{
{
Expression
*
ve
=
Expression
::
make_var_reference
(
rv
,
e
->
location
());
Expression
*
ve
=
Expression
::
make_var_reference
(
rv
,
e
->
location
());
lhs
->
push_back
(
ve
);
lhs
->
push_back
(
ve
);
...
@@ -2614,13 +2655,28 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
...
@@ -2614,13 +2655,28 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
;
;
else
if
(
lhs
->
size
()
==
1
)
else
if
(
lhs
->
size
()
==
1
)
{
{
b
->
add_statement
(
Statement
::
make_assignment
(
lhs
->
front
(),
rhs
->
front
(),
Statement
*
s
=
Statement
::
make_assignment
(
lhs
->
front
(),
rhs
->
front
(),
loc
));
loc
);
if
(
this
->
are_hidden_fields_ok_
)
{
Assignment_statement
*
as
=
static_cast
<
Assignment_statement
*>
(
s
);
as
->
set_hidden_fields_are_ok
();
}
b
->
add_statement
(
s
);
delete
lhs
;
delete
lhs
;
delete
rhs
;
delete
rhs
;
}
}
else
else
b
->
add_statement
(
Statement
::
make_tuple_assignment
(
lhs
,
rhs
,
loc
));
{
Statement
*
s
=
Statement
::
make_tuple_assignment
(
lhs
,
rhs
,
loc
);
if
(
this
->
are_hidden_fields_ok_
)
{
Tuple_assignment_statement
*
tas
=
static_cast
<
Tuple_assignment_statement
*>
(
s
);
tas
->
set_hidden_fields_are_ok
();
}
b
->
add_statement
(
s
);
}
b
->
add_statement
(
this
);
b
->
add_statement
(
this
);
...
@@ -2670,7 +2726,7 @@ Return_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
...
@@ -2670,7 +2726,7 @@ Return_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
// Make a return statement.
// Make a return statement.
S
tatement
*
Return_s
tatement
*
Statement
::
make_return_statement
(
Expression_list
*
vals
,
Statement
::
make_return_statement
(
Expression_list
*
vals
,
source_location
location
)
source_location
location
)
{
{
...
...
gcc/go/gofrontend/statements.h
View file @
280deda6
...
@@ -204,7 +204,7 @@ class Statement
...
@@ -204,7 +204,7 @@ class Statement
make_defer_statement
(
Call_expression
*
call
,
source_location
);
make_defer_statement
(
Call_expression
*
call
,
source_location
);
// Make a return statement.
// Make a return statement.
static
S
tatement
*
static
Return_s
tatement
*
make_return_statement
(
Expression_list
*
,
source_location
);
make_return_statement
(
Expression_list
*
,
source_location
);
// Make a break statement.
// Make a break statement.
...
@@ -482,13 +482,20 @@ class Temporary_statement : public Statement
...
@@ -482,13 +482,20 @@ class Temporary_statement : public Statement
public
:
public
:
Temporary_statement
(
Type
*
type
,
Expression
*
init
,
source_location
location
)
Temporary_statement
(
Type
*
type
,
Expression
*
init
,
source_location
location
)
:
Statement
(
STATEMENT_TEMPORARY
,
location
),
:
Statement
(
STATEMENT_TEMPORARY
,
location
),
type_
(
type
),
init_
(
init
),
bvariable_
(
NULL
),
is_address_taken_
(
false
)
type_
(
type
),
init_
(
init
),
bvariable_
(
NULL
),
are_hidden_fields_ok_
(
false
),
is_address_taken_
(
false
)
{
}
{
}
// Return the type of the temporary variable.
// Return the type of the temporary variable.
Type
*
Type
*
type
()
const
;
type
()
const
;
// Note that it is OK for this return statement to set hidden
// fields.
void
set_hidden_fields_are_ok
()
{
this
->
are_hidden_fields_ok_
=
true
;
}
// Record that something takes the address of this temporary
// Record that something takes the address of this temporary
// variable.
// variable.
void
void
...
@@ -526,6 +533,9 @@ class Temporary_statement : public Statement
...
@@ -526,6 +533,9 @@ class Temporary_statement : public Statement
Expression
*
init_
;
Expression
*
init_
;
// The backend representation of the temporary variable.
// The backend representation of the temporary variable.
Bvariable
*
bvariable_
;
Bvariable
*
bvariable_
;
// True if this statement may pass hidden fields in the return
// value. This is used for generated method stubs.
bool
are_hidden_fields_ok_
;
// True if something takes the address of this temporary variable.
// True if something takes the address of this temporary variable.
bool
is_address_taken_
;
bool
is_address_taken_
;
};
};
...
@@ -570,7 +580,7 @@ class Return_statement : public Statement
...
@@ -570,7 +580,7 @@ class Return_statement : public Statement
public
:
public
:
Return_statement
(
Expression_list
*
vals
,
source_location
location
)
Return_statement
(
Expression_list
*
vals
,
source_location
location
)
:
Statement
(
STATEMENT_RETURN
,
location
),
:
Statement
(
STATEMENT_RETURN
,
location
),
vals_
(
vals
),
is_lowered_
(
false
)
vals_
(
vals
),
are_hidden_fields_ok_
(
false
),
is_lowered_
(
false
)
{
}
{
}
// The list of values being returned. This may be NULL.
// The list of values being returned. This may be NULL.
...
@@ -578,6 +588,12 @@ class Return_statement : public Statement
...
@@ -578,6 +588,12 @@ class Return_statement : public Statement
vals
()
const
vals
()
const
{
return
this
->
vals_
;
}
{
return
this
->
vals_
;
}
// Note that it is OK for this return statement to set hidden
// fields.
void
set_hidden_fields_are_ok
()
{
this
->
are_hidden_fields_ok_
=
true
;
}
protected
:
protected
:
int
int
do_traverse
(
Traverse
*
traverse
)
do_traverse
(
Traverse
*
traverse
)
...
@@ -602,6 +618,9 @@ class Return_statement : public Statement
...
@@ -602,6 +618,9 @@ class Return_statement : public Statement
private
:
private
:
// Return values. This may be NULL.
// Return values. This may be NULL.
Expression_list
*
vals_
;
Expression_list
*
vals_
;
// True if this statement may pass hidden fields in the return
// value. This is used for generated method stubs.
bool
are_hidden_fields_ok_
;
// True if this statement has been lowered.
// True if this statement has been lowered.
bool
is_lowered_
;
bool
is_lowered_
;
};
};
...
...
gcc/go/gofrontend/types.cc
View file @
280deda6
...
@@ -7414,7 +7414,13 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
...
@@ -7414,7 +7414,13 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
retvals
->
push_back
(
Expression
::
make_call_result
(
call
,
i
));
retvals
->
push_back
(
Expression
::
make_call_result
(
call
,
i
));
}
}
Statement
*
retstat
=
Statement
::
make_return_statement
(
retvals
,
location
);
Return_statement
*
retstat
=
Statement
::
make_return_statement
(
retvals
,
location
);
// We can return values with hidden fields from a stub. This is
// necessary if the method is itself hidden.
retstat
->
set_hidden_fields_are_ok
();
gogo
->
add_statement
(
retstat
);
gogo
->
add_statement
(
retstat
);
}
}
}
}
...
...
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