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
c0328be3
Commit
c0328be3
authored
Feb 08, 2016
by
Jason Merrill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* convert.c (convert_to_integer_1): Re-indent.
From-SVN: r233217
parent
415594bb
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
215 additions
and
214 deletions
+215
-214
gcc/convert.c
+215
-214
No files found.
gcc/convert.c
View file @
c0328be3
...
@@ -670,229 +670,230 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
...
@@ -670,229 +670,230 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
make a wider result--are handled by "shorten" in build_binary_op. */
make a wider result--are handled by "shorten" in build_binary_op. */
if
(
dofold
)
if
(
dofold
)
switch
(
ex_form
)
switch
(
ex_form
)
{
case
RSHIFT_EXPR
:
/* We can pass truncation down through right shifting
when the shift count is a nonpositive constant. */
if
(
TREE_CODE
(
TREE_OPERAND
(
expr
,
1
))
==
INTEGER_CST
&&
tree_int_cst_sgn
(
TREE_OPERAND
(
expr
,
1
))
<=
0
)
goto
trunc1
;
break
;
case
LSHIFT_EXPR
:
/* We can pass truncation down through left shifting
when the shift count is a nonnegative constant and
the target type is unsigned. */
if
(
TREE_CODE
(
TREE_OPERAND
(
expr
,
1
))
==
INTEGER_CST
&&
tree_int_cst_sgn
(
TREE_OPERAND
(
expr
,
1
))
>=
0
&&
TYPE_UNSIGNED
(
type
)
&&
TREE_CODE
(
TYPE_SIZE
(
type
))
==
INTEGER_CST
)
{
/* If shift count is less than the width of the truncated type,
really shift. */
if
(
tree_int_cst_lt
(
TREE_OPERAND
(
expr
,
1
),
TYPE_SIZE
(
type
)))
/* In this case, shifting is like multiplication. */
goto
trunc1
;
else
{
/* If it is >= that width, result is zero.
Handling this with trunc1 would give the wrong result:
(int) ((long long) a << 32) is well defined (as 0)
but (int) a << 32 is undefined and would get a
warning. */
tree
t
=
build_int_cst
(
type
,
0
);
/* If the original expression had side-effects, we must
preserve it. */
if
(
TREE_SIDE_EFFECTS
(
expr
))
return
build2
(
COMPOUND_EXPR
,
type
,
expr
,
t
);
else
return
t
;
}
}
break
;
case
TRUNC_DIV_EXPR
:
{
{
tree
arg0
=
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
);
case
RSHIFT_EXPR
:
tree
arg1
=
get_unwidened
(
TREE_OPERAND
(
expr
,
1
),
type
);
/* We can pass truncation down through right shifting
when the shift count is a nonpositive constant. */
/* Don't distribute unless the output precision is at least as big
if
(
TREE_CODE
(
TREE_OPERAND
(
expr
,
1
))
==
INTEGER_CST
as the actual inputs and it has the same signedness. */
&&
tree_int_cst_sgn
(
TREE_OPERAND
(
expr
,
1
))
<=
0
)
if
(
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
&&
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg1
))
/* If signedness of arg0 and arg1 don't match,
we can't necessarily find a type to compare them in. */
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
==
TYPE_UNSIGNED
(
TREE_TYPE
(
arg1
)))
/* Do not change the sign of the division. */
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
expr
))
==
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
)))
/* Either require unsigned division or a division by
a constant that is not -1. */
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
||
(
TREE_CODE
(
arg1
)
==
INTEGER_CST
&&
!
integer_all_onesp
(
arg1
))))
goto
trunc1
;
goto
trunc1
;
break
;
break
;
}
case
MAX_EXPR
:
case
LSHIFT_EXPR
:
case
MIN_EXPR
:
/* We can pass truncation down through left shifting
case
MULT_EXPR
:
when the shift count is a nonnegative constant and
{
the target type is unsigned. */
tree
arg0
=
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
);
if
(
TREE_CODE
(
TREE_OPERAND
(
expr
,
1
))
==
INTEGER_CST
tree
arg1
=
get_unwidened
(
TREE_OPERAND
(
expr
,
1
),
type
);
&&
tree_int_cst_sgn
(
TREE_OPERAND
(
expr
,
1
))
>=
0
&&
TYPE_UNSIGNED
(
type
)
/* Don't distribute unless the output precision is at least as big
&&
TREE_CODE
(
TYPE_SIZE
(
type
))
==
INTEGER_CST
)
as the actual inputs. Otherwise, the comparison of the
truncated values will be wrong. */
if
(
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
&&
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg1
))
/* If signedness of arg0 and arg1 don't match,
we can't necessarily find a type to compare them in. */
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
==
TYPE_UNSIGNED
(
TREE_TYPE
(
arg1
))))
goto
trunc1
;
break
;
}
case
PLUS_EXPR
:
case
MINUS_EXPR
:
case
BIT_AND_EXPR
:
case
BIT_IOR_EXPR
:
case
BIT_XOR_EXPR
:
trunc1:
{
tree
arg0
=
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
);
tree
arg1
=
get_unwidened
(
TREE_OPERAND
(
expr
,
1
),
type
);
/* Do not try to narrow operands of pointer subtraction;
that will interfere with other folding. */
if
(
ex_form
==
MINUS_EXPR
&&
CONVERT_EXPR_P
(
arg0
)
&&
CONVERT_EXPR_P
(
arg1
)
&&
POINTER_TYPE_P
(
TREE_TYPE
(
TREE_OPERAND
(
arg0
,
0
)))
&&
POINTER_TYPE_P
(
TREE_TYPE
(
TREE_OPERAND
(
arg1
,
0
))))
break
;
if
(
outprec
>=
BITS_PER_WORD
||
TRULY_NOOP_TRUNCATION
(
outprec
,
inprec
)
||
inprec
>
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
||
inprec
>
TYPE_PRECISION
(
TREE_TYPE
(
arg1
)))
{
{
/* Do the arithmetic in type TYPEX,
/* If shift count is less than the width of the truncated type,
then convert result to TYPE. */
really shift. */
tree
typex
=
type
;
if
(
tree_int_cst_lt
(
TREE_OPERAND
(
expr
,
1
),
TYPE_SIZE
(
type
)))
/* In this case, shifting is like multiplication. */
/* Can't do arithmetic in enumeral types
goto
trunc1
;
so use an integer type that will hold the values. */
else
if
(
TREE_CODE
(
typex
)
==
ENUMERAL_TYPE
)
typex
=
lang_hooks
.
types
.
type_for_size
(
TYPE_PRECISION
(
typex
),
TYPE_UNSIGNED
(
typex
));
/* But now perhaps TYPEX is as wide as INPREC.
In that case, do nothing special here.
(Otherwise would recurse infinitely in convert. */
if
(
TYPE_PRECISION
(
typex
)
!=
inprec
)
{
{
/* Don't do unsigned arithmetic where signed was wanted,
/* If it is >= that width, result is zero.
or vice versa.
Handling this with trunc1 would give the wrong result:
Exception: if both of the original operands were
(int) ((long long) a << 32) is well defined (as 0)
unsigned then we can safely do the work as unsigned.
but (int) a << 32 is undefined and would get a
Exception: shift operations take their type solely
warning. */
from the first argument.
Exception: the LSHIFT_EXPR case above requires that
tree
t
=
build_int_cst
(
type
,
0
);
we perform this operation unsigned lest we produce
signed-overflow undefinedness.
/* If the original expression had side-effects, we must
And we may need to do it as unsigned
preserve it. */
if we truncate to the original size. */
if
(
TREE_SIDE_EFFECTS
(
expr
))
if
(
TYPE_UNSIGNED
(
TREE_TYPE
(
expr
))
return
build2
(
COMPOUND_EXPR
,
type
,
expr
,
t
);
||
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg1
))
||
ex_form
==
LSHIFT_EXPR
||
ex_form
==
RSHIFT_EXPR
||
ex_form
==
LROTATE_EXPR
||
ex_form
==
RROTATE_EXPR
))
||
ex_form
==
LSHIFT_EXPR
/* If we have !flag_wrapv, and either ARG0 or
ARG1 is of a signed type, we have to do
PLUS_EXPR, MINUS_EXPR or MULT_EXPR in an unsigned
type in case the operation in outprec precision
could overflow. Otherwise, we would introduce
signed-overflow undefinedness. */
||
((
!
TYPE_OVERFLOW_WRAPS
(
TREE_TYPE
(
arg0
))
||
!
TYPE_OVERFLOW_WRAPS
(
TREE_TYPE
(
arg1
)))
&&
((
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
*
2u
>
outprec
)
||
(
TYPE_PRECISION
(
TREE_TYPE
(
arg1
))
*
2u
>
outprec
))
&&
(
ex_form
==
PLUS_EXPR
||
ex_form
==
MINUS_EXPR
||
ex_form
==
MULT_EXPR
)))
{
if
(
!
TYPE_UNSIGNED
(
typex
))
typex
=
unsigned_type_for
(
typex
);
}
else
else
{
return
t
;
if
(
TYPE_UNSIGNED
(
typex
))
typex
=
signed_type_for
(
typex
);
}
/* We should do away with all this once we have a proper
type promotion/demotion pass, see PR45397. */
expr
=
maybe_fold_build2_loc
(
dofold
,
loc
,
ex_form
,
typex
,
convert
(
typex
,
arg0
),
convert
(
typex
,
arg1
));
return
convert
(
type
,
expr
);
}
}
}
}
}
break
;
break
;
case
NEGATE_EXPR
:
case
TRUNC_DIV_EXPR
:
case
BIT_NOT_EXPR
:
{
/* This is not correct for ABS_EXPR,
tree
arg0
=
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
);
since we must test the sign before truncation. */
tree
arg1
=
get_unwidened
(
TREE_OPERAND
(
expr
,
1
),
type
);
{
/* Do the arithmetic in type TYPEX,
/* Don't distribute unless the output precision is at least as
then convert result to TYPE. */
big as the actual inputs and it has the same signedness. */
tree
typex
=
type
;
if
(
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
&&
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg1
))
/* Can't do arithmetic in enumeral types
/* If signedness of arg0 and arg1 don't match,
so use an integer type that will hold the values. */
we can't necessarily find a type to compare them in. */
if
(
TREE_CODE
(
typex
)
==
ENUMERAL_TYPE
)
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
typex
==
TYPE_UNSIGNED
(
TREE_TYPE
(
arg1
)))
=
lang_hooks
.
types
.
type_for_size
(
TYPE_PRECISION
(
typex
),
/* Do not change the sign of the division. */
TYPE_UNSIGNED
(
typex
));
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
expr
))
==
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
)))
if
(
!
TYPE_UNSIGNED
(
typex
))
/* Either require unsigned division or a division by
typex
=
unsigned_type_for
(
typex
);
a constant that is not -1. */
return
convert
(
type
,
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
fold_build1
(
ex_form
,
typex
,
||
(
TREE_CODE
(
arg1
)
==
INTEGER_CST
convert
(
typex
,
&&
!
integer_all_onesp
(
arg1
))))
TREE_OPERAND
(
expr
,
0
))));
goto
trunc1
;
}
break
;
}
CASE_CONVERT:
case
MAX_EXPR
:
/* Don't introduce a
case
MIN_EXPR
:
"can't convert between vector values of different size" error. */
case
MULT_EXPR
:
if
(
TREE_CODE
(
TREE_TYPE
(
TREE_OPERAND
(
expr
,
0
)))
==
VECTOR_TYPE
{
&&
(
GET_MODE_SIZE
(
TYPE_MODE
(
TREE_TYPE
(
TREE_OPERAND
(
expr
,
0
))))
tree
arg0
=
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
);
!=
GET_MODE_SIZE
(
TYPE_MODE
(
type
))))
tree
arg1
=
get_unwidened
(
TREE_OPERAND
(
expr
,
1
),
type
);
/* Don't distribute unless the output precision is at least as
big as the actual inputs. Otherwise, the comparison of the
truncated values will be wrong. */
if
(
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
&&
outprec
>=
TYPE_PRECISION
(
TREE_TYPE
(
arg1
))
/* If signedness of arg0 and arg1 don't match,
we can't necessarily find a type to compare them in. */
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
==
TYPE_UNSIGNED
(
TREE_TYPE
(
arg1
))))
goto
trunc1
;
break
;
}
case
PLUS_EXPR
:
case
MINUS_EXPR
:
case
BIT_AND_EXPR
:
case
BIT_IOR_EXPR
:
case
BIT_XOR_EXPR
:
trunc1:
{
tree
arg0
=
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
);
tree
arg1
=
get_unwidened
(
TREE_OPERAND
(
expr
,
1
),
type
);
/* Do not try to narrow operands of pointer subtraction;
that will interfere with other folding. */
if
(
ex_form
==
MINUS_EXPR
&&
CONVERT_EXPR_P
(
arg0
)
&&
CONVERT_EXPR_P
(
arg1
)
&&
POINTER_TYPE_P
(
TREE_TYPE
(
TREE_OPERAND
(
arg0
,
0
)))
&&
POINTER_TYPE_P
(
TREE_TYPE
(
TREE_OPERAND
(
arg1
,
0
))))
break
;
if
(
outprec
>=
BITS_PER_WORD
||
TRULY_NOOP_TRUNCATION
(
outprec
,
inprec
)
||
inprec
>
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
||
inprec
>
TYPE_PRECISION
(
TREE_TYPE
(
arg1
)))
{
/* Do the arithmetic in type TYPEX,
then convert result to TYPE. */
tree
typex
=
type
;
/* Can't do arithmetic in enumeral types
so use an integer type that will hold the values. */
if
(
TREE_CODE
(
typex
)
==
ENUMERAL_TYPE
)
typex
=
lang_hooks
.
types
.
type_for_size
(
TYPE_PRECISION
(
typex
),
TYPE_UNSIGNED
(
typex
));
/* But now perhaps TYPEX is as wide as INPREC.
In that case, do nothing special here.
(Otherwise would recurse infinitely in convert. */
if
(
TYPE_PRECISION
(
typex
)
!=
inprec
)
{
/* Don't do unsigned arithmetic where signed was wanted,
or vice versa.
Exception: if both of the original operands were
unsigned then we can safely do the work as unsigned.
Exception: shift operations take their type solely
from the first argument.
Exception: the LSHIFT_EXPR case above requires that
we perform this operation unsigned lest we produce
signed-overflow undefinedness.
And we may need to do it as unsigned
if we truncate to the original size. */
if
(
TYPE_UNSIGNED
(
TREE_TYPE
(
expr
))
||
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg0
))
&&
(
TYPE_UNSIGNED
(
TREE_TYPE
(
arg1
))
||
ex_form
==
LSHIFT_EXPR
||
ex_form
==
RSHIFT_EXPR
||
ex_form
==
LROTATE_EXPR
||
ex_form
==
RROTATE_EXPR
))
||
ex_form
==
LSHIFT_EXPR
/* If we have !flag_wrapv, and either ARG0 or
ARG1 is of a signed type, we have to do
PLUS_EXPR, MINUS_EXPR or MULT_EXPR in an unsigned
type in case the operation in outprec precision
could overflow. Otherwise, we would introduce
signed-overflow undefinedness. */
||
((
!
TYPE_OVERFLOW_WRAPS
(
TREE_TYPE
(
arg0
))
||
!
TYPE_OVERFLOW_WRAPS
(
TREE_TYPE
(
arg1
)))
&&
((
TYPE_PRECISION
(
TREE_TYPE
(
arg0
))
*
2u
>
outprec
)
||
(
TYPE_PRECISION
(
TREE_TYPE
(
arg1
))
*
2u
>
outprec
))
&&
(
ex_form
==
PLUS_EXPR
||
ex_form
==
MINUS_EXPR
||
ex_form
==
MULT_EXPR
)))
{
if
(
!
TYPE_UNSIGNED
(
typex
))
typex
=
unsigned_type_for
(
typex
);
}
else
{
if
(
TYPE_UNSIGNED
(
typex
))
typex
=
signed_type_for
(
typex
);
}
/* We should do away with all this once we have a proper
type promotion/demotion pass, see PR45397. */
expr
=
maybe_fold_build2_loc
(
dofold
,
loc
,
ex_form
,
typex
,
convert
(
typex
,
arg0
),
convert
(
typex
,
arg1
));
return
convert
(
type
,
expr
);
}
}
}
break
;
break
;
/* If truncating after truncating, might as well do all at once.
If truncating after extending, we may get rid of wasted work. */
case
NEGATE_EXPR
:
return
convert
(
type
,
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
));
case
BIT_NOT_EXPR
:
/* This is not correct for ABS_EXPR,
case
COND_EXPR
:
since we must test the sign before truncation. */
/* It is sometimes worthwhile to push the narrowing down through
{
the conditional and never loses. A COND_EXPR may have a throw
/* Do the arithmetic in type TYPEX,
as one operand, which then has void type. Just leave void
then convert result to TYPE. */
operands as they are. */
tree
typex
=
type
;
/* Can't do arithmetic in enumeral types
so use an integer type that will hold the values. */
if
(
TREE_CODE
(
typex
)
==
ENUMERAL_TYPE
)
typex
=
lang_hooks
.
types
.
type_for_size
(
TYPE_PRECISION
(
typex
),
TYPE_UNSIGNED
(
typex
));
if
(
!
TYPE_UNSIGNED
(
typex
))
typex
=
unsigned_type_for
(
typex
);
return
convert
(
type
,
fold_build1
(
ex_form
,
typex
,
convert
(
typex
,
TREE_OPERAND
(
expr
,
0
))));
}
CASE_CONVERT:
/* Don't introduce a "can't convert between vector values of
different size" error. */
if
(
TREE_CODE
(
TREE_TYPE
(
TREE_OPERAND
(
expr
,
0
)))
==
VECTOR_TYPE
&&
(
GET_MODE_SIZE
(
TYPE_MODE
(
TREE_TYPE
(
TREE_OPERAND
(
expr
,
0
))))
!=
GET_MODE_SIZE
(
TYPE_MODE
(
type
))))
break
;
/* If truncating after truncating, might as well do all at once.
If truncating after extending, we may get rid of wasted work. */
return
convert
(
type
,
get_unwidened
(
TREE_OPERAND
(
expr
,
0
),
type
));
case
COND_EXPR
:
/* It is sometimes worthwhile to push the narrowing down through
the conditional and never loses. A COND_EXPR may have a throw
as one operand, which then has void type. Just leave void
operands as they are. */
return
return
fold_build3
(
COND_EXPR
,
type
,
TREE_OPERAND
(
expr
,
0
),
fold_build3
(
COND_EXPR
,
type
,
TREE_OPERAND
(
expr
,
0
),
VOID_TYPE_P
(
TREE_TYPE
(
TREE_OPERAND
(
expr
,
1
)))
VOID_TYPE_P
(
TREE_TYPE
(
TREE_OPERAND
(
expr
,
1
)))
...
@@ -902,9 +903,9 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
...
@@ -902,9 +903,9 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
?
TREE_OPERAND
(
expr
,
2
)
?
TREE_OPERAND
(
expr
,
2
)
:
convert
(
type
,
TREE_OPERAND
(
expr
,
2
)));
:
convert
(
type
,
TREE_OPERAND
(
expr
,
2
)));
default:
default:
break
;
break
;
}
}
/* When parsing long initializers, we might end up with a lot of casts.
/* When parsing long initializers, we might end up with a lot of casts.
Shortcut this. */
Shortcut this. */
...
...
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