This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/2227: generates unsigned compare in comparison of int to sizeof()
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/2227: generates unsigned compare in comparison of int to sizeof()
- From: LathamCD at navair dot navy dot mil
- Date: 8 Mar 2001 15:44:15 -0000
- Cc: HueyAL at navair dot navy dot mil
- Reply-To: LathamCD at navair dot navy dot mil
>Number: 2227
>Category: c
>Synopsis: generates unsigned compare in comparison of int to sizeof()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Thu Mar 08 07:46:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Chris Latham
>Release: cygnus-2.7.2-960126
>Organization:
>Environment:
Pentium Xeon-based PC using the Motorola 68k GCC targeting a 68060 processor
>Description:
The following code generates an unsigned comparison when a signed comparison is obviously intended:
if(((int) end_address - (int) begin_address) > (sizeof(RCCS_DATA) * 4) ||
(end_address > Idtable[rccs_id]->raw_data_end_address) ||
(end_address < Idtable[rccs_id]->raw_data_begin_address))
{
printf("Entered Conditional\n");
memcpy((char *) &IDtable[rccs_id],(char *)Idtable[rccs_id],sizeof(IDTABLE_DATA));
return;
}
The pertinent values are as follows:
int *begin_address = 0x100F7834
int *end_address = 0x100F3834
int *raw_data_begin_address = 0x100F3834
int *raw_data_end_address = 0x100F9834
sizeof(RCCS_DATA) = 8212
Using the '-S' option, the assembly output is as follows:
movel a6@(12),a6@(-16)
movel a6@(16),a6@(-20)
clrl a6@(-8)
movel a6@(-20),d0
subl a6@(-16),d0
cmpl #32848,d0
jhi L3
The conditional block is entered, and the printf() is seen even though the condition is not satisfied. I believe this is because BHI (JHI above) does an unsigned comparison of the values resulting in the negative left-value being larger than the right-value.
>How-To-Repeat:
Compile the code above in the ANSI C compiler mode.
>Fix:
The problem was solved by adding a cast to type int in front of the sizeof(). This would seem to indicate that sizeof() is being promoted to an unsigned int and that the conditional further promotes the left-value to an unsigned int when it is clearly intended to be an int. The corrected code is as follows:
if(((int) end_address - (int) begin_address) > (int)(sizeof(RCCS_DATA) * 4) ||
(end_address > Idtable[rccs_id]->raw_data_end_address) ||
(end_address < Idtable[rccs_id]->raw_data_begin_address))
{
printf("Entered Conditional\n");
memcpy((char *) &IDtable[rccs_id],(char *)Idtable[rccs_id],sizeof(IDTABLE_DATA));
return;
}
This generates the expected assembly output:
movel a6@(12),a6@(-16)
movel a6@(16),a6@(-20)
clrl a6@(-8)
movel a6@(-20),d0
subl a6@(-16),d0
cmpl #32848,d0
jgt L3
The BGT (JGT above) instruction is what we were looking for to begin with.
>Release-Note:
>Audit-Trail:
>Unformatted: