Bug 84816 - [7.2.0/8.0.1 x86_64] Incorrect code generation if signed overflow
Summary: [7.2.0/8.0.1 x86_64] Incorrect code generation if signed overflow
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-03-11 02:10 UTC by Dmitry Lesnikov
Modified: 2018-03-11 18:05 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Lesnikov 2018-03-11 02:10:17 UTC
Hello!

# g++-7 --version
g++-7 (Ubuntu 7.2.0-8ubuntu3.1~16.04.york0) 7.2.0

# g++-8 --version
g++-8 (Ubuntu 8-20180218-1ubuntu1~16.04.york0) 8.0.1 20180218 (experimental) [trunk revision 257787]

c++ code <sigover.cpp>:

#include <stdio.h>

class C1 {};

int main(void)
{
   C1 c1;
   int a = 0x7FFFFFFA;
   for(int i=0; i<10; i++)
      printf("%d\n", ++a);
   return 0;
}


g++-7[8] -O2 -S sigover.cpp

the loop assembler code with error:
.L2:
	addl	$1, %ebx
	movl	$.LC0, %esi
	movl	$1, %edi
	movl	%ebx, %edx
	xorl	%eax, %eax
	call	__printf_chk
	jmp	.L2                <-- infinite loop
	.cfi_endproc
.LFE30:

g++-7[8] -O1 -S sigover.cpp

the loop assembler code without error:
.L2:
	addl	$1, %ebx
	movl	%ebx, %edx
	movl	$.LC0, %esi
	movl	$1, %edi
	movl	$0, %eax
	call	__printf_chk
	cmpl	$-2147483644, %ebx    <-- check the end of loop
	jne	.L2
	movl	$0, %eax
	popq	%rbx
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE30:

if comment 1st line in main:
// C1 c1;
then g++-7 -O2 correctly generates the code
but g++-8 -O2 still makes an infinite loop
Comment 1 Andrew Pinski 2018-03-11 02:15:48 UTC
signed overflow is undefined behavior at runtime.
Comment 2 Dmitry Lesnikov 2018-03-11 02:22:39 UTC
gcc 5.4.1 make correct code.
Comment 3 Andrew Pinski 2018-03-11 02:25:38 UTC
Does not matter, the behavior is undefined.
Comment 4 Dmitry Lesnikov 2018-03-11 02:26:56 UTC
(In reply to Andrew Pinski from comment #1)
> signed overflow is undefined behavior at runtime.

for(int i=0; i<10; i++)

this loop is correct.
Comment 5 Andrew Pinski 2018-03-11 02:32:59 UTC
(In reply to Dmitry Lesnikov from comment #4)
> (In reply to Andrew Pinski from comment #1)
> > signed overflow is undefined behavior at runtime.
> 
> for(int i=0; i<10; i++)
> 
> this loop is correct.

But there is an overflow with the variable a when i is 6.
Comment 6 Dmitry Lesnikov 2018-03-11 02:37:18 UTC
(In reply to Andrew Pinski from comment #5)
> (In reply to Dmitry Lesnikov from comment #4)
> > (In reply to Andrew Pinski from comment #1)
> > > signed overflow is undefined behavior at runtime.
> > 
> > for(int i=0; i<10; i++)
> > 
> > this loop is correct.
> 
> But there is an overflow with the variable a when i is 6.

Yes, but code generation incorrect. It's not runtime yet.
Comment 7 Dmitry Lesnikov 2018-03-11 02:39:49 UTC
(In reply to Andrew Pinski from comment #5)
> (In reply to Dmitry Lesnikov from comment #4)
> > (In reply to Andrew Pinski from comment #1)
> > > signed overflow is undefined behavior at runtime.
> > 
> > for(int i=0; i<10; i++)
> > 
> > this loop is correct.
> 
> But there is an overflow with the variable a when i is 6.

Why does the line
C1 c1;
affect the behavior of the loop?
Comment 8 Eric Botcazou 2018-03-11 18:05:55 UTC
> Yes, but code generation incorrect. It's not runtime yet.

The criterion is as follows: does the code invoke undefined behavior when executed in the abstract machine specified by the C standard?  If so, then the compiler is allowed to generate object code that does anything, including playing some music or erasing the hard drive; here it generates an infinite loop and that's OK.