]> git.pld-linux.org Git - packages/gcc4.git/blob - gcc4-pr19606.patch
- added from gcc/
[packages/gcc4.git] / gcc4-pr19606.patch
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
43 Index: 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.075122 seconds and 3 git commands to generate.