diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-03-21 18:57:34 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-03-21 18:57:34 +0100 |
commit | 126e660935733b9141a2bc23dec3ed25fa339310 (patch) | |
tree | a599d6407fcac6fa3c455a61f9abe5fc1d927338 /gcc | |
parent | 9dfd55f55b725d4e20f18e2824b7193d7ffd8715 (diff) | |
download | gcc-126e660935733b9141a2bc23dec3ed25fa339310.zip gcc-126e660935733b9141a2bc23dec3ed25fa339310.tar.gz gcc-126e660935733b9141a2bc23dec3ed25fa339310.tar.bz2 |
re PR c/42544 (Bad codegen with signed short cast to unsigned int, then promoted to unsigned long long)
PR c/42544
PR c/48197
* c-common.c (shorten_compare): If primopN is first sign-extended
to opN and then zero-extended to result type, set primopN to opN.
* gcc.c-torture/execute/pr42544.c: New test.
* gcc.c-torture/execute/pr48197.c: New test.
From-SVN: r171252
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr42544.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr48197.c | 25 |
5 files changed, 67 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 921109a..7296dec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-03-20 Jakub Jelinek <jakub@redhat.com> + + PR c/42544 + PR c/48197 + * c-common.c (shorten_compare): If primopN is first sign-extended + to opN and then zero-extended to result type, set primopN to opN. + 2011-03-21 Daniel Jacobowitz <dan@codesourcery.com> * config/arm/unwind-arm.c (__gnu_unwind_pr_common): Correct test diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 3f1b964..33af3d8 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -3301,6 +3301,20 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, primop0 = get_narrower (op0, &unsignedp0); primop1 = get_narrower (op1, &unsignedp1); + /* If primopN is first sign-extended from primopN's precision to opN's + precision, then zero-extended from opN's precision to + *restype_ptr precision, shortenings might be invalid. */ + if (TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (TREE_TYPE (op0)) + && TYPE_PRECISION (TREE_TYPE (op0)) < TYPE_PRECISION (*restype_ptr) + && !unsignedp0 + && TYPE_UNSIGNED (TREE_TYPE (op0))) + primop0 = op0; + if (TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (TREE_TYPE (op1)) + && TYPE_PRECISION (TREE_TYPE (op1)) < TYPE_PRECISION (*restype_ptr) + && !unsignedp1 + && TYPE_UNSIGNED (TREE_TYPE (op1))) + primop1 = op1; + /* Handle the case that OP0 does not *contain* a conversion but it *requires* conversion to FINAL_TYPE. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 97fa329..cc8d145 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-03-20 Jakub Jelinek <jakub@redhat.com> + + PR c/42544 + PR c/48197 + * gcc.c-torture/execute/pr42544.c: New test. + * gcc.c-torture/execute/pr48197.c: New test. + 2011-03-21 Michael Meissner <meissner@linux.vnet.ibm.com> PR preprocessor/48192 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr42544.c b/gcc/testsuite/gcc.c-torture/execute/pr42544.c new file mode 100644 index 0000000..c5951b0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr42544.c @@ -0,0 +1,14 @@ +/* PR c/42544 */ + +extern void abort (void); + +int +main () +{ + signed short s = -1; + if (sizeof (long long) == sizeof (unsigned int)) + return 0; + if ((unsigned int) s >= 0x100000000ULL) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr48197.c b/gcc/testsuite/gcc.c-torture/execute/pr48197.c new file mode 100644 index 0000000..37812c0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr48197.c @@ -0,0 +1,25 @@ +/* PR c/48197 */ + +extern void abort (void); +static int y = 0x8000; + +int +main () +{ + unsigned int x = (short)y; + if (sizeof (0LL) == sizeof (0U)) + return 0; + if (0LL > (0U ^ (short)-0x8000)) + abort (); + if (0LL > (0U ^ x)) + abort (); + if (0LL > (0U ^ (short)y)) + abort (); + if ((0U ^ (short)-0x8000) < 0LL) + abort (); + if ((0U ^ x) < 0LL) + abort (); + if ((0U ^ (short)y) < 0LL) + abort (); + return 0; +} |