public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/97884] New: INT_MIN falsely expanded to 64 bit
@ 2020-11-18  7:08 s.bauroth@tu-berlin.de
  2020-11-18  7:08 ` [Bug c/97884] " s.bauroth@tu-berlin.de
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: s.bauroth@tu-berlin.de @ 2020-11-18  7:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

            Bug ID: 97884
           Summary: INT_MIN falsely expanded to 64 bit
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: s.bauroth@tu-berlin.de
  Target Milestone: ---

Created attachment 49583
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49583&action=edit
example file

arm-none-eabi-gcc: when compiling

printf("%i\n", -2147483648);
printf("%i\n", (int)-2147483648);

INT_MIN in the first call gets recognized as a 64 bit argument and split across
r2 and r3. r1 remains untouched. In the second call, INT_MIN is correctly put
into r1:

   8:   e3a02102        mov     r2, #-2147483648        ; 0x80000000
   c:   e3e03000        mvn     r3, #0
  10:   e59f0010        ldr     r0, [pc, #16]           ; 28
<start_kernel+0x28>
  14:   ebfffffe        bl      0 <printf>
  18:   e3a01102        mov     r1, #-2147483648        ; 0x80000000
  1c:   e59f0004        ldr     r0, [pc, #4]            ; 28
<start_kernel+0x28>
  20:   ebfffffe        bl      0 <printf>

Source file attached was compiled with
arm-none-eabi-gcc -v -save-temps -c start.c -o start.o

gcc 10.2.0 was configured with
--target=arm-none-eabi --prefix=$(PREFIX) --enable-interwork
--enable-languages="c" --with-newlib --without-headers --disable-nls

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
@ 2020-11-18  7:08 ` s.bauroth@tu-berlin.de
  2020-11-18  8:25 ` rguenth at gcc dot gnu.org
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: s.bauroth@tu-berlin.de @ 2020-11-18  7:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #1 from s.bauroth@tu-berlin.de ---
Created attachment 49584
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49584&action=edit
preprocessed source

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
  2020-11-18  7:08 ` [Bug c/97884] " s.bauroth@tu-berlin.de
@ 2020-11-18  8:25 ` rguenth at gcc dot gnu.org
  2020-11-18 16:04 ` msebor at gcc dot gnu.org
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-11-18  8:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
You need to write -2147483647 - 1 to make it 'int', -2147483648 are two tokens
and the second is too large for int.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
  2020-11-18  7:08 ` [Bug c/97884] " s.bauroth@tu-berlin.de
  2020-11-18  8:25 ` rguenth at gcc dot gnu.org
@ 2020-11-18 16:04 ` msebor at gcc dot gnu.org
  2020-11-18 16:23 ` s.bauroth@tu-berlin.de
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-11-18 16:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |msebor at gcc dot gnu.org

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
Compiling with -Wall should issue a warning pointing out the problem:

$ cat pr97884.c && gcc -O2 -S -Wall pr97884.c
void f (void)
{
  __builtin_printf ("%i\n", -2147483648);
  __builtin_printf ("%i\n", (int)-2147483648);
}


pr97884.c: In function 'f':
pr97884.c:3:23: warning: format '%i' expects argument of type 'int', but
argument 2 has type 'long long int' [-Wformat=]
    3 |   __builtin_printf ("%i\n", -2147483648);
      |                      ~^     ~~~~~~~~~~~
      |                       |     |
      |                       int   long long int
      |                      %lli

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (2 preceding siblings ...)
  2020-11-18 16:04 ` msebor at gcc dot gnu.org
@ 2020-11-18 16:23 ` s.bauroth@tu-berlin.de
  2020-11-18 16:29 ` jakub at gcc dot gnu.org
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: s.bauroth@tu-berlin.de @ 2020-11-18 16:23 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #4 from s.bauroth@tu-berlin.de ---
I am aware of the warning, I disagree with it's content. INT_MIN is an int, not
a long long int. I understand why it is processed as a long long int
internally, but that should not be visible from the outside world, at least
imho.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (3 preceding siblings ...)
  2020-11-18 16:23 ` s.bauroth@tu-berlin.de
@ 2020-11-18 16:29 ` jakub at gcc dot gnu.org
  2020-11-18 16:40 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-18 16:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
But INT_MIN in C is (-2147483647 - 1) for 32-bit ints, not -2147483648, as has
been explained, there is a significant difference for those two, because
2147483648 constant is not representable in int and therefore the constant gets
a different type and the negation preserves that type.
If something defines INT_MIN to -2147483648, the bug is in whatever defines it
that way.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (4 preceding siblings ...)
  2020-11-18 16:29 ` jakub at gcc dot gnu.org
@ 2020-11-18 16:40 ` redi at gcc dot gnu.org
  2020-11-18 16:51 ` s.bauroth@tu-berlin.de
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-18 16:40 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The C standard says "The type of an integer constant is the first of the
corresponding list in which its value can be represented." The corresponding
list for decimal constants with no suffix is int, long int, long long int.

Since 2147483647 doesn't fit in int, it will have a larger type (long long int
for your target). The unary - operator changes the value, but it still has type
long long int.

If you use INT_MIN from <limits.h> it will work, because that's defined as
(-INT_MAX - 1) as Richard and Jakub said. It's defined like that for a good
reason.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (5 preceding siblings ...)
  2020-11-18 16:40 ` redi at gcc dot gnu.org
@ 2020-11-18 16:51 ` s.bauroth@tu-berlin.de
  2020-11-18 16:57 ` jakub at gcc dot gnu.org
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: s.bauroth@tu-berlin.de @ 2020-11-18 16:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #7 from s.bauroth@tu-berlin.de ---
I do understand that +2147483648 is not an int. I am aware of how the 2s
complement works. It seems to me the reason for INT_MIN being '(-2147483647 -
1)' instead of the mathematically equivalent '-2147483648' is the parser
tokenizing the absolute value of the literal split from the sign of the
literal. I'm also able to imagine why that eases parsing. But if splitting
absolute value and sign - why not treat the absolute value as unsigned? Or
maybe do a check 'in the end' (I have no knowledge of the codebase here...)
whether one can reduce the size of the literal again?
The fact is INT_MIN and '-2147483648' are both integers perfectly representable
in 32 bits. I understand why gcc treats the second one differently (and clang
does too) - I just think it's not right (or expectable for that matter). And if
it's right, gcc should maybe warn about a 32bit literal being expanded to a
larger type - not only in format strings.

> The type of an integer constant is the first of the corresponding list in which its value can be represented.
These kind of sentences make me think gcc's behaviour is wrong. The number can
be represented in 32 bits.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (6 preceding siblings ...)
  2020-11-18 16:51 ` s.bauroth@tu-berlin.de
@ 2020-11-18 16:57 ` jakub at gcc dot gnu.org
  2020-11-18 17:03 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-11-18 16:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
If you design your own programming language, you can define it whatever way you
want, but for C and C++ it is well defined how the compiler must behave in
these cases, that -2147483648 are two separate tokens, unary minus and an
integral constant.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (7 preceding siblings ...)
  2020-11-18 16:57 ` jakub at gcc dot gnu.org
@ 2020-11-18 17:03 ` redi at gcc dot gnu.org
  2020-11-18 17:24 ` s.bauroth@tu-berlin.de
  2020-11-18 18:06 ` schwab@linux-m68k.org
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-18 17:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to s.bauroth from comment #7)
> > The type of an integer constant is the first of the corresponding list
> > in which its value can be represented.
> These kind of sentences make me think gcc's behaviour is wrong. The number
> can be represented in 32 bits.

No it can't.

A few paragraphs above the text I quoted last time it says:L

"An integer constant begins with a digit, but has no period or exponent part.
It may have a prefix that specifies its base and a suffix that specifies its
type."

So the - sign is not part of the constant. The constant is 2147483648 and that
doesn't fit in 32 bits. So it's a 64-bit type, and then that gets negated.

That has been explained several times now.

"I don't understand C and I won't read the spec" is not a GCC bug.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (8 preceding siblings ...)
  2020-11-18 17:03 ` redi at gcc dot gnu.org
@ 2020-11-18 17:24 ` s.bauroth@tu-berlin.de
  2020-11-18 18:06 ` schwab@linux-m68k.org
  10 siblings, 0 replies; 12+ messages in thread
From: s.bauroth@tu-berlin.de @ 2020-11-18 17:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #10 from s.bauroth@tu-berlin.de ---
(In reply to Jonathan Wakely from comment #9)
> (In reply to s.bauroth from comment #7)
> > > The type of an integer constant is the first of the corresponding list
> > > in which its value can be represented.
> > These kind of sentences make me think gcc's behaviour is wrong. The number
> > can be represented in 32 bits.

> So the - sign is not part of the constant. The constant is 2147483648 and
> that doesn't fit in 32 bits. So it's a 64-bit type, and then that gets
> negated.
If the constant is not allowed to have a sign why try to press it into a signed
type? I know it's the standard that does it - but does it make any sense?

> That has been explained several times now.
And I said multiple times that I understand the reasoning.

> "I don't understand C and I won't read the spec" is not a GCC bug.
Not going to comment.

I'm not questioning your reading of the standard, I'm not saying gcc breaks the
standard. From a programmers perspective it's not intuitive that 'INT_MIN',
'-2147483647 - 1' and all the other forms (like int a = -2147483648;
printf("%i", a);' work, but '-2147483648' does not. And from a technical
perspective it is absolutely unnecessary. Despite what the standard says about
how to tokenize the number , it fits in 32 bits. It just does.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c/97884] INT_MIN falsely expanded to 64 bit
  2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
                   ` (9 preceding siblings ...)
  2020-11-18 17:24 ` s.bauroth@tu-berlin.de
@ 2020-11-18 18:06 ` schwab@linux-m68k.org
  10 siblings, 0 replies; 12+ messages in thread
From: schwab@linux-m68k.org @ 2020-11-18 18:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97884

--- Comment #11 from Andreas Schwab <schwab@linux-m68k.org> ---
2147483648 does not fit in 32 bits.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-11-18 18:06 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-18  7:08 [Bug c/97884] New: INT_MIN falsely expanded to 64 bit s.bauroth@tu-berlin.de
2020-11-18  7:08 ` [Bug c/97884] " s.bauroth@tu-berlin.de
2020-11-18  8:25 ` rguenth at gcc dot gnu.org
2020-11-18 16:04 ` msebor at gcc dot gnu.org
2020-11-18 16:23 ` s.bauroth@tu-berlin.de
2020-11-18 16:29 ` jakub at gcc dot gnu.org
2020-11-18 16:40 ` redi at gcc dot gnu.org
2020-11-18 16:51 ` s.bauroth@tu-berlin.de
2020-11-18 16:57 ` jakub at gcc dot gnu.org
2020-11-18 17:03 ` redi at gcc dot gnu.org
2020-11-18 17:24 ` s.bauroth@tu-berlin.de
2020-11-18 18:06 ` schwab@linux-m68k.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).