Bug 63803 - When GCC 4.9.2 compile with option -O2, the target is error.
Summary: When GCC 4.9.2 compile with option -O2, the target is error.
Status: CLOSED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-10 09:57 UTC by Airbak
Modified: 2014-11-10 11:49 UTC (History)
3 users (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 Airbak 2014-11-10 09:57:27 UTC
The option -fisolate-erroneous-paths-dereference in -O2 causes it.
1.file b.c:
int main()
{
    //volatile unsigned int
	//unsigned int orgin = *((int *)0);   //ok
	//unsigned int orgin = *((unsigned int *)0); //ok
	unsigned int orgin = *((volatile unsigned int *)0);   //nok
	printf("---");
	
	return 0;
}

2.compile:
arm-none-eabi-gcc --specs=nosys.specs -O2 b.c -o b
or
arm-none-eabi-gcc --specs=nosys.specs -O1 -fisolate-erroneous-paths-dereference b.c -o b

3.asm
00008210 <main>:
    8210:	e3a03000 	mov	r3, #0
    8214:	e5933000 	ldr	r3, [r3]
    8218:	e7f000f0 	udf	#0


4.question:
Why it is "udf	#0"?  
Is it a BUG?
Please help me, thanks!
Comment 1 Marek Polacek 2014-11-10 10:04:49 UTC
I don't know why this would be a bug.  You're dereferencin a NULL pointer.  udf is an undefined instruction.  On x86_64 you'd get the ud2 instruction.
Comment 2 Andrew Pinski 2014-11-10 10:06:10 UTC
Dereferencing a null pointer is undefined. -fisolate-erroneous-paths-dereference changes some of them into __builtin_trap and for arm that is udf #0.
Comment 3 Airbak 2014-11-10 11:14:39 UTC
Thank you for your reply!
"-fisolate-erroneous-paths-dereference" is a new option in GCC-4.9.x.
When I use GCC-4.8.x, it is OK and will not have this problem.
More and more people are switching GCC4.8 to GCC4.9, I think they will meet this problem too. Please help me and tell me how to solve it, thanks.


1.
This code run after DDR init. DDR address range is 0x0 to 0x80000000.
Some operation will get and set the address 0x0.
  
2.
*((unsigned int *)0) is OK
*((volatile unsigned int *)0)  is not OK.
Why the "volatile"  makes different?

3. 
If I want to use option "-O2" and not contain "-fisolate-erroneous-paths-dereference", how should I configure to compile a cross-toolchain with  GCC-4.9.2?
I mean when  compile a file  with command "gcc -O2 a.c",  it will not contain option "-fisolate-erroneous-paths-dereference".
like:
$SRCDIR/$GCC/configure --target=$TARGET \
    --prefix=$INSTALLDIR_NATIVE \
    --libexecdir=$INSTALLDIR_NATIVE/lib \
    --infodir=$INSTALLDIR_NATIVE_DOC/info \
    --mandir=$INSTALLDIR_NATIVE_DOC/man \
    --htmldir=$INSTALLDIR_NATIVE_DOC/html \
    --pdfdir=$INSTALLDIR_NATIVE_DOC/pdf \
    --enable-languages=c,c++ \
    --enable-plugins \
    --disable-decimal-float \
    --disable-libffi \
    --disable-libgomp \
    --disable-libmudflap \
    --disable-libquadmath \
    --disable-libssp \
    --disable-libstdcxx-pch \
    ...
Comment 4 ktkachov 2014-11-10 11:18:46 UTC
The problem here is that the code uses undefined behaviour according to the C standard (dereferencing NULL pointer), therefore the compiler is free to do whatever it wants. The user code should be fixed to not do that.

GCC 4.9 is free to change its behaviour from 4.8 in such code because it makes (and shouldn't make) no guarantees about undefined behaviour
Comment 5 Marek Polacek 2014-11-10 11:21:08 UTC
(In reply to Airbak from comment #3) 
> 2.
> *((unsigned int *)0) is OK
> *((volatile unsigned int *)0)  is not OK.
> Why the "volatile"  makes different?

Because volatile prevents the compiler from optimizing that statement out.  As stated above, dereferencing a NULL pointer is undefined, so if you do that, all bets are off.

You can use -fno-isolate-erroneous-paths-dereference, but I think the problem is elsewhere.
Comment 6 Marc Glisse 2014-11-10 11:36:10 UTC
If dereferencing 0 is ok on your platform, you need at least -fno-delete-null-pointer-checks. I don't know if the isolate pass checks that flag though (it probably should).
Comment 7 Airbak 2014-11-10 11:49:43 UTC
Thank you for all reply, it could be closed.