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
d4157849
Commit
d4157849
authored
Jan 24, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Better handling of erroneous function signatures.
From-SVN: r183479
parent
00a42fb3
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
140 additions
and
26 deletions
+140
-26
gcc/go/gofrontend/expressions.cc
+14
-6
gcc/go/gofrontend/expressions.h
+13
-2
gcc/go/gofrontend/gogo-tree.cc
+4
-0
gcc/go/gofrontend/gogo.cc
+31
-9
gcc/go/gofrontend/gogo.h
+21
-0
gcc/go/gofrontend/parse.cc
+55
-9
gcc/go/gofrontend/parse.h
+2
-0
No files found.
gcc/go/gofrontend/expressions.cc
View file @
d4157849
...
...
@@ -1455,8 +1455,9 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
{
if
(
this
->
is_composite_literal_key_
)
return
this
;
error_at
(
location
,
"reference to undefined name %qs"
,
this
->
named_object_
->
message_name
().
c_str
());
if
(
!
this
->
no_error_message_
)
error_at
(
location
,
"reference to undefined name %qs"
,
this
->
named_object_
->
message_name
().
c_str
());
return
Expression
::
make_error
(
location
);
}
}
...
...
@@ -1469,8 +1470,9 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
case
Named_object
:
:
NAMED_OBJECT_TYPE_DECLARATION
:
if
(
this
->
is_composite_literal_key_
)
return
this
;
error_at
(
location
,
"reference to undefined type %qs"
,
real
->
message_name
().
c_str
());
if
(
!
this
->
no_error_message_
)
error_at
(
location
,
"reference to undefined type %qs"
,
real
->
message_name
().
c_str
());
return
Expression
::
make_error
(
location
);
case
Named_object
:
:
NAMED_OBJECT_VAR
:
real
->
var_value
()
->
set_is_used
();
...
...
@@ -1481,7 +1483,8 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
case
Named_object
:
:
NAMED_OBJECT_PACKAGE
:
if
(
this
->
is_composite_literal_key_
)
return
this
;
error_at
(
location
,
"unexpected reference to package"
);
if
(
!
this
->
no_error_message_
)
error_at
(
location
,
"unexpected reference to package"
);
return
Expression
::
make_error
(
location
);
default
:
go_unreachable
();
...
...
@@ -1499,7 +1502,7 @@ Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
// Make a reference to an unknown name.
E
xpression
*
Unknown_e
xpression
*
Expression
::
make_unknown_reference
(
Named_object
*
no
,
Location
location
)
{
return
new
Unknown_expression
(
no
,
location
);
...
...
@@ -8483,6 +8486,11 @@ Builtin_call_expression::do_check_types(Gogo*)
||
type
->
function_type
()
!=
NULL
||
type
->
is_slice_type
())
;
else
if
((
*
p
)
->
is_type_expression
())
{
// If this is a type expression it's going to give
// an error anyhow, so we don't need one here.
}
else
this
->
report_error
(
_
(
"unsupported argument type to "
"builtin function"
));
...
...
gcc/go/gofrontend/expressions.h
View file @
d4157849
...
...
@@ -153,7 +153,7 @@ class Expression
// Make a reference to an unknown name. In a correct program this
// will always be lowered to a real const/var/func reference.
static
E
xpression
*
static
Unknown_e
xpression
*
make_unknown_reference
(
Named_object
*
,
Location
);
// Make a constant bool expression.
...
...
@@ -1554,7 +1554,8 @@ class Unknown_expression : public Parser_expression
public
:
Unknown_expression
(
Named_object
*
named_object
,
Location
location
)
:
Parser_expression
(
EXPRESSION_UNKNOWN_REFERENCE
,
location
),
named_object_
(
named_object
),
is_composite_literal_key_
(
false
)
named_object_
(
named_object
),
no_error_message_
(
false
),
is_composite_literal_key_
(
false
)
{
}
// The associated named object.
...
...
@@ -1566,6 +1567,13 @@ class Unknown_expression : public Parser_expression
const
std
::
string
&
name
()
const
;
// Call this to indicate that we should not give an error if this
// name is never defined. This is used to avoid knock-on errors
// during an erroneous parse.
void
set_no_error_message
()
{
this
->
no_error_message_
=
true
;
}
// Note that this expression is being used as the key in a composite
// literal, so it may be OK if it is not resolved.
void
...
...
@@ -1592,6 +1600,9 @@ class Unknown_expression : public Parser_expression
private
:
// The unknown name.
Named_object
*
named_object_
;
// True if we should not give errors if this is undefined. This is
// used if there was a parse failure.
bool
no_error_message_
;
// True if this is the key in a composite literal.
bool
is_composite_literal_key_
;
};
...
...
gcc/go/gofrontend/gogo-tree.cc
View file @
d4157849
...
...
@@ -1108,6 +1108,10 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
}
break
;
case
NAMED_OBJECT_ERRONEOUS
:
decl
=
error_mark_node
;
break
;
default
:
go_unreachable
();
}
...
...
gcc/go/gofrontend/gogo.cc
View file @
d4157849
...
...
@@ -626,8 +626,8 @@ Gogo::start_function(const std::string& name, Function_type* type,
const
Typed_identifier
*
receiver
=
type
->
receiver
();
Variable
*
this_param
=
new
Variable
(
receiver
->
type
(),
NULL
,
false
,
true
,
true
,
location
);
std
::
string
name
=
receiver
->
name
();
if
(
name
.
empty
())
std
::
string
r
name
=
receiver
->
name
();
if
(
r
name
.
empty
())
{
// We need to give receivers a name since they wind up in
// DECL_ARGUMENTS. FIXME.
...
...
@@ -635,10 +635,10 @@ Gogo::start_function(const std::string& name, Function_type* type,
char
buf
[
50
];
snprintf
(
buf
,
sizeof
buf
,
"r.%u"
,
count
);
++
count
;
name
=
buf
;
r
name
=
buf
;
}
if
(
!
Gogo
::
is_sink_name
(
name
))
block
->
bindings
()
->
add_variable
(
name
,
NULL
,
this_param
);
if
(
!
Gogo
::
is_sink_name
(
r
name
))
block
->
bindings
()
->
add_variable
(
r
name
,
NULL
,
this_param
);
}
const
Typed_identifier_list
*
parameters
=
type
->
parameters
();
...
...
@@ -654,8 +654,8 @@ Gogo::start_function(const std::string& name, Function_type* type,
if
(
is_varargs
&&
p
+
1
==
parameters
->
end
())
param
->
set_is_varargs_parameter
();
std
::
string
name
=
p
->
name
();
if
(
name
.
empty
()
||
Gogo
::
is_sink_name
(
name
))
std
::
string
p
name
=
p
->
name
();
if
(
pname
.
empty
()
||
Gogo
::
is_sink_name
(
p
name
))
{
// We need to give parameters a name since they wind up
// in DECL_ARGUMENTS. FIXME.
...
...
@@ -663,9 +663,9 @@ Gogo::start_function(const std::string& name, Function_type* type,
char
buf
[
50
];
snprintf
(
buf
,
sizeof
buf
,
"p.%u"
,
count
);
++
count
;
name
=
buf
;
p
name
=
buf
;
}
block
->
bindings
()
->
add_variable
(
name
,
NULL
,
param
);
block
->
bindings
()
->
add_variable
(
p
name
,
NULL
,
param
);
}
}
...
...
@@ -834,6 +834,14 @@ Gogo::finish_block(Location location)
return
block
;
}
// Add an erroneous name.
Named_object
*
Gogo
::
add_erroneous_name
(
const
std
::
string
&
name
)
{
return
this
->
package_
->
bindings
()
->
add_erroneous_name
(
name
);
}
// Add an unknown name.
Named_object
*
...
...
@@ -3522,6 +3530,7 @@ Block::traverse(Traverse* traverse)
case
Named_object
:
:
NAMED_OBJECT_TYPE_DECLARATION
:
case
Named_object
:
:
NAMED_OBJECT_UNKNOWN
:
case
Named_object
:
:
NAMED_OBJECT_ERRONEOUS
:
break
;
case
Named_object
:
:
NAMED_OBJECT_PACKAGE
:
...
...
@@ -4521,6 +4530,9 @@ Named_object::location() const
case
NAMED_OBJECT_UNINITIALIZED
:
go_unreachable
();
case
NAMED_OBJECT_ERRONEOUS
:
return
Linemap
::
unknown_location
();
case
NAMED_OBJECT_UNKNOWN
:
return
this
->
unknown_value
()
->
location
();
...
...
@@ -4565,6 +4577,9 @@ Named_object::export_named_object(Export* exp) const
case
NAMED_OBJECT_UNKNOWN
:
go_unreachable
();
case
NAMED_OBJECT_ERRONEOUS
:
break
;
case
NAMED_OBJECT_CONST
:
this
->
const_value
()
->
export_const
(
exp
,
this
->
name_
);
break
;
...
...
@@ -4751,6 +4766,9 @@ Bindings::add_named_object_to_contour(Contour* contour,
Named_object
*
Bindings
::
new_definition
(
Named_object
*
old_object
,
Named_object
*
new_object
)
{
if
(
new_object
->
is_erroneous
()
&&
!
old_object
->
is_erroneous
())
return
new_object
;
std
::
string
reason
;
switch
(
old_object
->
classification
())
{
...
...
@@ -4758,6 +4776,9 @@ Bindings::new_definition(Named_object* old_object, Named_object* new_object)
case
Named_object
:
:
NAMED_OBJECT_UNINITIALIZED
:
go_unreachable
();
case
Named_object
:
:
NAMED_OBJECT_ERRONEOUS
:
return
old_object
;
case
Named_object
:
:
NAMED_OBJECT_UNKNOWN
:
{
Named_object
*
real
=
old_object
->
unknown_value
()
->
real_named_object
();
...
...
@@ -5003,6 +5024,7 @@ Bindings::traverse(Traverse* traverse, bool is_global)
case
Named_object
:
:
NAMED_OBJECT_TYPE_DECLARATION
:
case
Named_object
:
:
NAMED_OBJECT_FUNC_DECLARATION
:
case
Named_object
:
:
NAMED_OBJECT_UNKNOWN
:
case
Named_object
:
:
NAMED_OBJECT_ERRONEOUS
:
break
;
case
Named_object
:
:
NAMED_OBJECT_SINK
:
...
...
gcc/go/gofrontend/gogo.h
View file @
d4157849
...
...
@@ -267,6 +267,11 @@ class Gogo
Block
*
finish_block
(
Location
);
// Declare an erroneous name. This is used to avoid knock-on errors
// after a parsing error.
Named_object
*
add_erroneous_name
(
const
std
::
string
&
name
);
// Declare an unknown name. This is used while parsing. The name
// must be resolved by the end of the parse. Unknown names are
// always added at the package level.
...
...
@@ -1688,6 +1693,9 @@ class Named_object
{
// An uninitialized Named_object. We should never see this.
NAMED_OBJECT_UNINITIALIZED
,
// An erroneous name. This indicates a parse error, to avoid
// later errors about undefined references.
NAMED_OBJECT_ERRONEOUS
,
// An unknown name. This is used for forward references. In a
// correct program, these will all be resolved by the end of the
// parse.
...
...
@@ -1720,6 +1728,10 @@ class Named_object
// Classifiers.
bool
is_erroneous
()
const
{
return
this
->
classification_
==
NAMED_OBJECT_ERRONEOUS
;
}
bool
is_unknown
()
const
{
return
this
->
classification_
==
NAMED_OBJECT_UNKNOWN
;
}
...
...
@@ -1762,6 +1774,10 @@ class Named_object
// Creators.
static
Named_object
*
make_erroneous_name
(
const
std
::
string
&
name
)
{
return
new
Named_object
(
name
,
NULL
,
NAMED_OBJECT_ERRONEOUS
);
}
static
Named_object
*
make_unknown_name
(
const
std
::
string
&
name
,
Location
);
static
Named_object
*
...
...
@@ -2032,6 +2048,11 @@ class Bindings
Bindings
(
Bindings
*
enclosing
);
// Add an erroneous name.
Named_object
*
add_erroneous_name
(
const
std
::
string
&
name
)
{
return
this
->
add_named_object
(
Named_object
::
make_erroneous_name
(
name
));
}
// Add an unknown name.
Named_object
*
add_unknown_name
(
const
std
::
string
&
name
,
Location
location
)
...
...
gcc/go/gofrontend/parse.cc
View file @
d4157849
...
...
@@ -45,6 +45,7 @@ Parse::Parse(Lex* lex, Gogo* gogo)
token_
(
Token
::
make_invalid_token
(
Linemap
::
unknown_location
())),
unget_token_
(
Token
::
make_invalid_token
(
Linemap
::
unknown_location
())),
unget_token_valid_
(
false
),
is_erroneous_function_
(
false
),
gogo_
(
gogo
),
break_stack_
(
NULL
),
continue_stack_
(
NULL
),
...
...
@@ -2123,8 +2124,6 @@ Parse::function_decl()
this
->
advance_token
();
Function_type
*
fntype
=
this
->
signature
(
rec
,
this
->
location
());
if
(
fntype
==
NULL
)
return
;
Named_object
*
named_object
=
NULL
;
...
...
@@ -2171,13 +2170,28 @@ Parse::function_decl()
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_LCURLY
))
{
if
(
named_object
==
NULL
&&
!
Gogo
::
is_sink_name
(
name
))
this
->
gogo_
->
declare_function
(
name
,
fntype
,
location
);
{
if
(
fntype
!=
NULL
)
this
->
gogo_
->
declare_function
(
name
,
fntype
,
location
);
else
this
->
gogo_
->
add_erroneous_name
(
name
);
}
}
else
{
bool
hold_is_erroneous_function
=
this
->
is_erroneous_function_
;
if
(
fntype
==
NULL
)
{
fntype
=
Type
::
make_function_type
(
NULL
,
NULL
,
NULL
,
location
);
this
->
is_erroneous_function_
=
true
;
if
(
!
Gogo
::
is_sink_name
(
name
))
this
->
gogo_
->
add_erroneous_name
(
name
);
name
=
this
->
gogo_
->
pack_hidden_name
(
"_"
,
false
);
}
this
->
gogo_
->
start_function
(
name
,
fntype
,
true
,
location
);
Location
end_loc
=
this
->
block
();
this
->
gogo_
->
finish_function
(
end_loc
);
this
->
is_erroneous_function_
=
hold_is_erroneous_function
;
}
}
...
...
@@ -2392,7 +2406,15 @@ Parse::operand(bool may_be_sink)
return
Expression
::
make_func_reference
(
named_object
,
NULL
,
location
);
case
Named_object
:
:
NAMED_OBJECT_UNKNOWN
:
return
Expression
::
make_unknown_reference
(
named_object
,
location
);
{
Unknown_expression
*
ue
=
Expression
::
make_unknown_reference
(
named_object
,
location
);
if
(
this
->
is_erroneous_function_
)
ue
->
set_no_error_message
();
return
ue
;
}
case
Named_object
:
:
NAMED_OBJECT_ERRONEOUS
:
return
Expression
::
make_error
(
location
);
default
:
go_unreachable
();
}
...
...
@@ -2698,14 +2720,22 @@ Parse::function_lit()
hold_enclosing_vars
.
swap
(
this
->
enclosing_vars_
);
Function_type
*
type
=
this
->
signature
(
NULL
,
location
);
bool
fntype_is_error
=
false
;
if
(
type
==
NULL
)
type
=
Type
::
make_function_type
(
NULL
,
NULL
,
NULL
,
location
);
{
type
=
Type
::
make_function_type
(
NULL
,
NULL
,
NULL
,
location
);
fntype_is_error
=
true
;
}
// For a function literal, the next token must be a '{'. If we
// don't see that, then we may have a type expression.
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_LCURLY
))
return
Expression
::
make_type
(
type
,
location
);
bool
hold_is_erroneous_function
=
this
->
is_erroneous_function_
;
if
(
fntype_is_error
)
this
->
is_erroneous_function_
=
true
;
Bc_stack
*
hold_break_stack
=
this
->
break_stack_
;
Bc_stack
*
hold_continue_stack
=
this
->
continue_stack_
;
this
->
break_stack_
=
NULL
;
...
...
@@ -2724,6 +2754,8 @@ Parse::function_lit()
this
->
break_stack_
=
hold_break_stack
;
this
->
continue_stack_
=
hold_continue_stack
;
this
->
is_erroneous_function_
=
hold_is_erroneous_function
;
hold_enclosing_vars
.
swap
(
this
->
enclosing_vars_
);
Expression
*
closure
=
this
->
create_closure
(
no
,
&
hold_enclosing_vars
,
...
...
@@ -3043,13 +3075,27 @@ Parse::id_to_expression(const std::string& name, Location location)
case
Named_object
:
:
NAMED_OBJECT_FUNC_DECLARATION
:
return
Expression
::
make_func_reference
(
named_object
,
NULL
,
location
);
case
Named_object
:
:
NAMED_OBJECT_UNKNOWN
:
return
Expression
::
make_unknown_reference
(
named_object
,
location
);
{
Unknown_expression
*
ue
=
Expression
::
make_unknown_reference
(
named_object
,
location
);
if
(
this
->
is_erroneous_function_
)
ue
->
set_no_error_message
();
return
ue
;
}
case
Named_object
:
:
NAMED_OBJECT_PACKAGE
:
case
Named_object
:
:
NAMED_OBJECT_TYPE
:
case
Named_object
:
:
NAMED_OBJECT_TYPE_DECLARATION
:
// These cases can arise for a field name in a composite
// literal.
return
Expression
::
make_unknown_reference
(
named_object
,
location
);
{
// These cases can arise for a field name in a composite
// literal.
Unknown_expression
*
ue
=
Expression
::
make_unknown_reference
(
named_object
,
location
);
if
(
this
->
is_erroneous_function_
)
ue
->
set_no_error_message
();
return
ue
;
}
case
Named_object
:
:
NAMED_OBJECT_ERRONEOUS
:
return
Expression
::
make_error
(
location
);
default
:
error_at
(
this
->
location
(),
"unexpected type of identifier"
);
return
Expression
::
make_error
(
location
);
...
...
gcc/go/gofrontend/parse.h
View file @
d4157849
...
...
@@ -305,6 +305,8 @@ class Parse
Token
unget_token_
;
// Whether unget_token_ is valid.
bool
unget_token_valid_
;
// Whether the function we are parsing had errors in the signature.
bool
is_erroneous_function_
;
// The code we are generating.
Gogo
*
gogo_
;
// A stack of statements for which break may be used.
...
...
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