summaryrefslogtreecommitdiff
path: root/gcc/c-convert.c
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1992-09-11 07:35:32 +0000
committerRichard Stallman <rms@gnu.org>1992-09-11 07:35:32 +0000
commit1f0c5cc9cf4410e18aec390311de0e7b2956b5da (patch)
treed4861f32a0e2f4c55407e310723743b5366a2e76 /gcc/c-convert.c
parent4f61da45f3adde8926a3f4894fdee2b4c0a13887 (diff)
downloadgcc-1f0c5cc9cf4410e18aec390311de0e7b2956b5da.tar.gz
(convert_to_integer): Don't pass truncation thru lshift if shift count >= width of narrower type.
(convert_to_integer): Don't pass truncation thru lshift if shift count >= width of narrower type. Instead, just use 0. From-SVN: r2104
Diffstat (limited to 'gcc/c-convert.c')
-rw-r--r--gcc/c-convert.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index b160fd1b1ac..89637cb7364 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -187,9 +187,21 @@ convert_to_integer (type, expr)
/* We can pass truncation down through left shifting
when the shift count is a nonnegative constant. */
if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
- && ! tree_int_cst_lt (TREE_OPERAND (expr, 1), integer_zero_node))
- /* In this case, shifting is like multiplication. */
- goto trunc1;
+ && ! tree_int_cst_lt (TREE_OPERAND (expr, 1), integer_zero_node)
+ && 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. */
+ return convert_to_integer (type, integer_zero_node);
+ }
break;
case MAX_EXPR: