]> git.pld-linux.org Git - packages/gcc4.git/blame - gcc4-pr19606.patch
- added from gcc/
[packages/gcc4.git] / gcc4-pr19606.patch
CommitLineData
4ada39a3
AM
1--- gcc/c-typeck.c (revision 110241)
2+++ gcc/c-typeck.c (working copy)
3@@ -8101,12 +8101,35 @@ build_binary_op (enum tree_code code, tr
4 if (shorten && none_complex)
5 {
6 int unsigned0, unsigned1;
7- tree arg0 = get_narrower (op0, &unsigned0);
8- tree arg1 = get_narrower (op1, &unsigned1);
9- /* UNS is 1 if the operation to be done is an unsigned one. */
10- int uns = TYPE_UNSIGNED (result_type);
11+ tree arg0, arg1;
12+ int uns;
13 tree type;
14
15+ /* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
16+ excessive narrowing when we call get_narrower below. For
17+ example, suppose that OP0 is of unsigned int extended
18+ from signed char and that RESULT_TYPE is long long int.
19+ If we explicitly cast OP0 to RESULT_TYPE, OP0 would look
20+ like
21+
22+ (long long int) (unsigned int) signed_char
23+
24+ which get_narrower would narrow down to
25+
26+ (unsigned int) signed char
27+
28+ If we do not cast OP0 first, get_narrower would return
29+ signed_char, which is inconsistent with the case of the
30+ explicit cast. */
31+ op0 = convert (result_type, op0);
32+ op1 = convert (result_type, op1);
33+
34+ arg0 = get_narrower (op0, &unsigned0);
35+ arg1 = get_narrower (op1, &unsigned1);
36+
37+ /* UNS is 1 if the operation to be done is an unsigned one. */
38+ uns = TYPE_UNSIGNED (result_type);
39+
40 final_type = result_type;
41
42 /* Handle the case that OP0 (or OP1) does not *contain* a conversion
43Index: testsuite/gcc.c-torture/execute/pr19606.c
44===================================================================
45--- /dev/null 2005-09-01 09:08:28.063949816 -0700
46+++ gcc/testsuite/gcc.c-torture/execute/pr19606.c 2006-01-15 14:41:56.490361111 -0800
47@@ -0,0 +1,33 @@
48+/* PR c/19606
49+ The C front end used to shorten the type of a division even when
50+ the signedness changes. Make sure that won't happen. */
51+
52+signed char a = -4;
53+
54+int
55+foo (void)
56+{
57+ return ((unsigned int) (signed int) a) / 2LL;
58+}
59+
60+int
61+bar (void)
62+{
63+ return ((unsigned int) (signed int) a) % 5LL;
64+}
65+
66+int
67+main (void)
68+{
69+ int r;
70+
71+ r = foo ();
72+ if (r != ((unsigned int) (signed int) (signed char) -4) / 2LL)
73+ abort ();
74+
75+ r = bar ();
76+ if (r != ((unsigned int) (signed int) (signed char) -4) % 5LL)
77+ abort ();
78+
79+ exit (0);
80+}
81
This page took 0.036352 seconds and 4 git commands to generate.