diff options
author | rms <rms@138bc75d-0d04-0410-961f-82ee72b054a4> | 1992-09-11 07:35:32 +0000 |
---|---|---|
committer | rms <rms@138bc75d-0d04-0410-961f-82ee72b054a4> | 1992-09-11 07:35:32 +0000 |
commit | ad59b569036d9ac5496c2b82ec9f233bdd8d6322 (patch) | |
tree | d4861f32a0e2f4c55407e310723743b5366a2e76 /gcc/c-convert.c | |
parent | 52d54ca88b23d423bd30c64b551f113b7a8c2718 (diff) | |
download | gcc-ad59b569036d9ac5496c2b82ec9f233bdd8d6322.tar.gz |
(convert_to_integer): Don't pass truncation thru lshift
if shift count >= width of narrower type. Instead, just use 0.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@2104 138bc75d-0d04-0410-961f-82ee72b054a4
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: |