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
405c87c4
Commit
405c87c4
authored
Dec 03, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Fix nil func panics, constant type conversions.
From-SVN: r194064
parent
9b8a4017
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
63 deletions
+98
-63
gcc/go/gofrontend/expressions.cc
+96
-61
gcc/go/gofrontend/expressions.h
+2
-2
No files found.
gcc/go/gofrontend/expressions.cc
View file @
405c87c4
...
...
@@ -2965,46 +2965,6 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
{
if
(
!
nc
.
set_type
(
type
,
true
,
location
))
return
Expression
::
make_error
(
location
);
// Don't simply convert to or from a float or complex type
// with a different size. That may change the value.
Type
*
vtype
=
val
->
type
();
if
(
vtype
->
is_abstract
())
;
else
if
(
type
->
float_type
()
!=
NULL
)
{
if
(
vtype
->
float_type
()
!=
NULL
)
{
if
(
type
->
float_type
()
->
bits
()
!=
vtype
->
float_type
()
->
bits
())
return
this
;
}
else
if
(
vtype
->
complex_type
()
!=
NULL
)
{
if
(
type
->
float_type
()
->
bits
()
*
2
!=
vtype
->
complex_type
()
->
bits
())
return
this
;
}
}
else
if
(
type
->
complex_type
()
!=
NULL
)
{
if
(
vtype
->
complex_type
()
!=
NULL
)
{
if
(
type
->
complex_type
()
->
bits
()
!=
vtype
->
complex_type
()
->
bits
())
return
this
;
}
else
if
(
vtype
->
float_type
()
!=
NULL
)
{
if
(
type
->
complex_type
()
->
bits
()
!=
vtype
->
float_type
()
->
bits
()
*
2
)
return
this
;
}
}
else
if
(
vtype
->
float_type
()
!=
NULL
)
return
this
;
else
if
(
vtype
->
complex_type
()
!=
NULL
)
return
this
;
return
nc
.
expression
(
location
);
}
}
...
...
@@ -9239,6 +9199,9 @@ Call_expression::do_get_tree(Translate_context* context)
}
}
if
(
func
==
NULL
)
fn
=
save_expr
(
fn
);
tree
ret
=
build_call_array
(
excess_type
!=
NULL_TREE
?
excess_type
:
rettype
,
fn
,
nargs
,
args
);
delete
[]
args
;
...
...
@@ -9272,6 +9235,24 @@ Call_expression::do_get_tree(Translate_context* context)
if
(
this
->
results_
!=
NULL
)
ret
=
this
->
set_results
(
context
,
ret
);
// We can't unwind the stack past a call to nil, so we need to
// insert an explicit check so that the panic can be recovered.
if
(
func
==
NULL
)
{
tree
compare
=
fold_build2_loc
(
location
.
gcc_location
(),
EQ_EXPR
,
boolean_type_node
,
fn
,
fold_convert_loc
(
location
.
gcc_location
(),
TREE_TYPE
(
fn
),
null_pointer_node
));
tree
crash
=
build3_loc
(
location
.
gcc_location
(),
COND_EXPR
,
void_type_node
,
compare
,
gogo
->
runtime_error
(
RUNTIME_ERROR_NIL_DEREFERENCE
,
location
),
NULL_TREE
);
ret
=
fold_build2_loc
(
location
.
gcc_location
(),
COMPOUND_EXPR
,
TREE_TYPE
(
ret
),
crash
,
ret
);
}
this
->
tree_
=
ret
;
return
ret
;
...
...
@@ -14229,7 +14210,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
bool
Numeric_constant
::
check_float_type
(
Float_type
*
type
,
bool
issue_error
,
Location
location
)
const
Location
location
)
{
mpfr_t
val
;
switch
(
this
->
classification_
)
...
...
@@ -14282,6 +14263,29 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
}
ret
=
exp
<=
max_exp
;
if
(
ret
)
{
// Round the constant to the desired type.
mpfr_t
t
;
mpfr_init
(
t
);
switch
(
type
->
bits
())
{
case
32
:
mpfr_set_prec
(
t
,
24
);
break
;
case
64
:
mpfr_set_prec
(
t
,
53
);
break
;
default
:
go_unreachable
();
}
mpfr_set
(
t
,
val
,
GMP_RNDN
);
mpfr_set
(
val
,
t
,
GMP_RNDN
);
mpfr_clear
(
t
);
this
->
set_float
(
type
,
val
);
}
}
mpfr_clear
(
val
);
...
...
@@ -14296,7 +14300,7 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
bool
Numeric_constant
::
check_complex_type
(
Complex_type
*
type
,
bool
issue_error
,
Location
location
)
const
Location
location
)
{
if
(
type
->
is_abstract
())
return
true
;
...
...
@@ -14315,46 +14319,77 @@ Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
}
mpfr_t
real
;
mpfr_t
imag
;
switch
(
this
->
classification_
)
{
case
NC_INT
:
case
NC_RUNE
:
mpfr_init_set_z
(
real
,
this
->
u_
.
int_val
,
GMP_RNDN
);
mpfr_init_set_ui
(
imag
,
0
,
GMP_RNDN
);
break
;
case
NC_FLOAT
:
mpfr_init_set
(
real
,
this
->
u_
.
float_val
,
GMP_RNDN
);
mpfr_init_set_ui
(
imag
,
0
,
GMP_RNDN
);
break
;
case
NC_COMPLEX
:
if
(
!
mpfr_nan_p
(
this
->
u_
.
complex_val
.
imag
)
&&
!
mpfr_inf_p
(
this
->
u_
.
complex_val
.
imag
)
&&
!
mpfr_zero_p
(
this
->
u_
.
complex_val
.
imag
))
{
if
(
mpfr_get_exp
(
this
->
u_
.
complex_val
.
imag
)
>
max_exp
)
{
if
(
issue_error
)
error_at
(
location
,
"complex imaginary part overflow"
);
return
false
;
}
}
mpfr_init_set
(
real
,
this
->
u_
.
complex_val
.
real
,
GMP_RNDN
);
mpfr_init_set
(
imag
,
this
->
u_
.
complex_val
.
imag
,
GMP_RNDN
);
break
;
default
:
go_unreachable
();
}
bool
ret
;
if
(
mpfr_nan_p
(
real
)
||
mpfr_inf_p
(
real
)
||
mpfr_zero_p
(
real
))
ret
=
true
;
else
ret
=
mpfr_get_exp
(
real
)
<=
max_exp
;
bool
ret
=
true
;
if
(
!
mpfr_nan_p
(
real
)
&&
!
mpfr_inf_p
(
real
)
&&
!
mpfr_zero_p
(
real
)
&&
mpfr_get_exp
(
real
)
>
max_exp
)
{
if
(
issue_error
)
error_at
(
location
,
"complex real part overflow"
);
ret
=
false
;
}
mpfr_clear
(
real
);
if
(
!
mpfr_nan_p
(
imag
)
&&
!
mpfr_inf_p
(
imag
)
&&
!
mpfr_zero_p
(
imag
)
&&
mpfr_get_exp
(
imag
)
>
max_exp
)
{
if
(
issue_error
)
error_at
(
location
,
"complex imaginary part overflow"
);
ret
=
false
;
}
if
(
!
ret
&&
issue_error
)
error_at
(
location
,
"complex real part overflow"
);
if
(
ret
)
{
// Round the constant to the desired type.
mpfr_t
t
;
mpfr_init
(
t
);
switch
(
type
->
bits
())
{
case
64
:
mpfr_set_prec
(
t
,
24
);
break
;
case
128
:
mpfr_set_prec
(
t
,
53
);
break
;
default
:
go_unreachable
();
}
mpfr_set
(
t
,
real
,
GMP_RNDN
);
mpfr_set
(
real
,
t
,
GMP_RNDN
);
mpfr_set
(
t
,
imag
,
GMP_RNDN
);
mpfr_set
(
imag
,
t
,
GMP_RNDN
);
mpfr_clear
(
t
);
this
->
set_complex
(
type
,
real
,
imag
);
}
mpfr_clear
(
real
);
mpfr_clear
(
imag
);
return
ret
;
}
...
...
gcc/go/gofrontend/expressions.h
View file @
405c87c4
...
...
@@ -2224,10 +2224,10 @@ class Numeric_constant
check_int_type
(
Integer_type
*
,
bool
,
Location
)
const
;
bool
check_float_type
(
Float_type
*
,
bool
,
Location
)
const
;
check_float_type
(
Float_type
*
,
bool
,
Location
);
bool
check_complex_type
(
Complex_type
*
,
bool
,
Location
)
const
;
check_complex_type
(
Complex_type
*
,
bool
,
Location
);
// The kinds of constants.
enum
Classification
...
...
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