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
6e25f095
Commit
6e25f095
authored
Dec 18, 2010
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Don't crash on recursive variables and typed consts.
From-SVN: r168012
parent
74841464
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
117 additions
and
8 deletions
+117
-8
gcc/go/gofrontend/expressions.cc
+69
-0
gcc/go/gofrontend/gogo.cc
+43
-8
gcc/go/gofrontend/gogo.h
+5
-0
No files found.
gcc/go/gofrontend/expressions.cc
View file @
6e25f095
...
...
@@ -2285,6 +2285,32 @@ Expression::make_complex(const mpfr_t* real, const mpfr_t* imag, Type* type,
return
new
Complex_expression
(
real
,
imag
,
type
,
location
);
}
// Find a named object in an expression.
class
Find_named_object
:
public
Traverse
{
public
:
Find_named_object
(
Named_object
*
no
)
:
Traverse
(
traverse_expressions
),
no_
(
no
),
found_
(
false
)
{
}
// Whether we found the object.
bool
found
()
const
{
return
this
->
found_
;
}
protected
:
int
expression
(
Expression
**
);
private
:
// The object we are looking for.
Named_object
*
no_
;
// Whether we found it.
bool
found_
;
};
// A reference to a const in an expression.
class
Const_expression
:
public
Expression
...
...
@@ -2295,6 +2321,10 @@ class Const_expression : public Expression
constant_
(
constant
),
type_
(
NULL
),
seen_
(
false
)
{
}
Named_object
*
named_object
()
{
return
this
->
constant_
;
}
const
std
::
string
&
name
()
const
{
return
this
->
constant_
->
name
();
}
...
...
@@ -2565,6 +2595,19 @@ Const_expression::do_determine_type(const Type_context* context)
void
Const_expression
::
do_check_types
(
Gogo
*
)
{
if
(
this
->
type_
!=
NULL
&&
this
->
type_
->
is_error_type
())
return
;
Expression
*
init
=
this
->
constant_
->
const_value
()
->
expr
();
Find_named_object
find_named_object
(
this
->
constant_
);
Expression
::
traverse
(
&
init
,
&
find_named_object
);
if
(
find_named_object
.
found
())
{
this
->
report_error
(
_
(
"constant refers to itself"
));
this
->
type_
=
Type
::
make_error_type
();
return
;
}
if
(
this
->
type_
==
NULL
||
this
->
type_
->
is_abstract
())
return
;
...
...
@@ -2682,6 +2725,32 @@ Expression::make_const_reference(Named_object* constant,
return
new
Const_expression
(
constant
,
location
);
}
// Find a named object in an expression.
int
Find_named_object
::
expression
(
Expression
**
pexpr
)
{
switch
((
*
pexpr
)
->
classification
())
{
case
Expression
:
:
EXPRESSION_CONST_REFERENCE
:
if
(
static_cast
<
Const_expression
*>
(
*
pexpr
)
->
named_object
()
==
this
->
no_
)
break
;
return
TRAVERSE_CONTINUE
;
case
Expression
:
:
EXPRESSION_VAR_REFERENCE
:
if
((
*
pexpr
)
->
var_expression
()
->
named_object
()
==
this
->
no_
)
break
;
return
TRAVERSE_CONTINUE
;
case
Expression
:
:
EXPRESSION_FUNC_REFERENCE
:
if
((
*
pexpr
)
->
func_expression
()
->
named_object
()
==
this
->
no_
)
break
;
return
TRAVERSE_CONTINUE
;
default
:
return
TRAVERSE_CONTINUE
;
}
this
->
found_
=
true
;
return
TRAVERSE_EXIT
;
}
// The nil value.
class
Nil_expression
:
public
Expression
...
...
gcc/go/gofrontend/gogo.cc
View file @
6e25f095
...
...
@@ -3056,7 +3056,7 @@ Variable::Variable(Type* type, Expression* init, bool is_global,
:
type_
(
type
),
init_
(
init
),
preinit_
(
NULL
),
location_
(
location
),
is_global_
(
is_global
),
is_parameter_
(
is_parameter
),
is_receiver_
(
is_receiver
),
is_varargs_parameter_
(
false
),
is_address_taken_
(
false
),
init_is_lowered_
(
false
),
is_address_taken_
(
false
),
seen_
(
false
),
init_is_lowered_
(
false
),
type_from_init_tuple_
(
false
),
type_from_range_index_
(
false
),
type_from_range_value_
(
false
),
type_from_chan_element_
(
false
),
is_type_switch_var_
(
false
)
...
...
@@ -3090,7 +3090,18 @@ Variable::lower_init_expression(Gogo* gogo, Named_object* function)
{
if
(
this
->
init_
!=
NULL
&&
!
this
->
init_is_lowered_
)
{
if
(
this
->
seen_
)
{
// We will give an error elsewhere, this is just to prevent
// an infinite loop.
return
;
}
this
->
seen_
=
true
;
gogo
->
lower_expression
(
function
,
&
this
->
init_
);
this
->
seen_
=
false
;
this
->
init_is_lowered_
=
true
;
}
}
...
...
@@ -3209,7 +3220,7 @@ Variable::type_from_chan_element(Expression* expr, bool report_error) const
// with type determination, then this should be unnecessary.
Type
*
Variable
::
type
()
const
Variable
::
type
()
{
// A variable in a type switch with a nil case will have the wrong
// type here. This gets fixed up in determine_type, below.
...
...
@@ -3224,14 +3235,26 @@ Variable::type() const
type
=
NULL
;
}
if
(
this
->
seen_
)
{
if
(
this
->
type_
==
NULL
||
!
this
->
type_
->
is_error_type
())
{
error_at
(
this
->
location_
,
"variable initializer refers to itself"
);
this
->
type_
=
Type
::
make_error_type
();
}
return
this
->
type_
;
}
this
->
seen_
=
true
;
if
(
type
!=
NULL
)
return
type
;
;
else
if
(
this
->
type_from_init_tuple_
)
return
this
->
type_from_tuple
(
init
,
false
);
type
=
this
->
type_from_tuple
(
init
,
false
);
else
if
(
this
->
type_from_range_index_
||
this
->
type_from_range_value_
)
return
this
->
type_from_range
(
init
,
this
->
type_from_range_index_
,
false
);
type
=
this
->
type_from_range
(
init
,
this
->
type_from_range_index_
,
false
);
else
if
(
this
->
type_from_chan_element_
)
return
this
->
type_from_chan_element
(
init
,
false
);
type
=
this
->
type_from_chan_element
(
init
,
false
);
else
{
gcc_assert
(
init
!=
NULL
);
...
...
@@ -3244,9 +3267,21 @@ Variable::type() const
if
(
type
->
is_void_type
())
type
=
Type
::
make_error_type
();
return
type
;
}
this
->
seen_
=
false
;
return
type
;
}
// Fetch the type from a const pointer, in which case it should have
// been set already.
Type
*
Variable
::
type
()
const
{
gcc_assert
(
this
->
type_
!=
NULL
);
return
this
->
type_
;
}
// Set the type if necessary.
...
...
gcc/go/gofrontend/gogo.h
View file @
6e25f095
...
...
@@ -1039,6 +1039,9 @@ class Variable
// Get the type of the variable.
Type
*
type
();
Type
*
type
()
const
;
// Return whether the type is defined yet.
...
...
@@ -1258,6 +1261,8 @@ class Variable
bool
is_varargs_parameter_
:
1
;
// Whether something takes the address of this variable.
bool
is_address_taken_
:
1
;
// True if we have seen this variable in a traversal.
bool
seen_
:
1
;
// True if we have lowered the initialization expression.
bool
init_is_lowered_
:
1
;
// True if init is a tuple used to set the type.
...
...
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