diff options
author | Richard Stallman <rms@gnu.org> | 1992-09-11 07:35:32 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1992-09-11 07:35:32 +0000 |
commit | 1f0c5cc9cf4410e18aec390311de0e7b2956b5da (patch) | |
tree | d4861f32a0e2f4c55407e310723743b5366a2e76 /gcc/c-convert.c | |
parent | 4f61da45f3adde8926a3f4894fdee2b4c0a13887 (diff) | |
download | gcc-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.c | 18 |
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: |