> Dale Johannesen wrote: >> Marius Wachtler wrote: >> ... >> The call to address 0 gets removed. >> >> define i32 @t(i32 %a) noreturn nounwind readnone { >> entry: >> unreachable >> } >> >> How can I prevent that the call is removed, without making the >> function addr volatile? >> Does anyone know which optimization removes it? > > Calling 0 is undefined behavior; the optimizer is within its rights to > remove this. Why do you want to call 0?Although a C translation unit may arguably not assign a correspondingly defined function as having a pointer value (address) comparing equal to ((void *) 0); it's not clear that the standard forbids the invocation of such a function, nor does it seem like a good idea to silently strip any such invocations especially if allowed to be specified; as to do so would seemingly only mask potentially legitimate problems, and/or prevent that intended from being performed although potentially relying on an undefined behavior. (As for example, it's not hard to imagine that it may be desirable to allow a machine which may trap such calls to do, and/or to allow the invocation of some otherwise specified behavior although considered undefined by standard itself.)
On Jun 9, 2009, at 10:02 AMPDT, Paul Schlie wrote:>> Dale Johannesen wrote: >>> Marius Wachtler wrote: >>> ... >>> The call to address 0 gets removed. >>> >>> define i32 @t(i32 %a) noreturn nounwind readnone { >>> entry: >>> unreachable >>> } >>> >>> How can I prevent that the call is removed, without making the >>> function addr volatile? >>> Does anyone know which optimization removes it? >> >> Calling 0 is undefined behavior; the optimizer is within its rights >> to >> remove this. Why do you want to call 0? > > Although a C translation unit may arguably not assign a > correspondingly > defined function as having a pointer value (address) comparing equal > to > ((void *) 0);Nothing arguable about it, see C99 6.3.2.3> it's not clear that the standard forbids the invocation of such a > functionNo such function can exist. I don't think the standard forbids you to call 0, but it makes calling 0 undefined behavior ("behavior, upon use of a nonportable or erroneous program construct or of erroneous data"), since there can't possibly be a valid function there.> nor does it seem like a good idea to silently strip any > such invocations especially if allowed to be specified; as to do so > would > seemingly only mask potentially legitimate problems, and/or prevent > that > intended from being performed although potentially relying on an > undefined > behavior. > > (As for example, it's not hard to imagine that it may be desirable > to allow > a machine which may trap such calls to do, and/or to allow the > invocation of > some otherwise specified behavior although considered undefined by > standard > itself.)In general, a C compiler is not the right tool to use for functionality outside the C language, so I'm not inclined to be sympathetic to this line of reasoning.
2009/6/9 Dale Johannesen <dalej at apple.com>:> >> >> Although a C translation unit may arguably not assign a >> correspondingly >> defined function as having a pointer value (address) comparing equal >> to >> ((void *) 0); > > Nothing arguable about it, see C99 6.3.2.3 > >> it's not clear that the standard forbids the invocation of such a >> function > > No such function can exist. I don't think the standard forbids you to > call 0, but it makes calling 0 undefined behavior ("behavior, upon use > of a nonportable or erroneous program construct or of erroneous > data"), since there can't possibly be a valid function there. >In C++, my understanding is that the null pointer -- static_cast<void*>(0) -- need not be the pointer whose representation is all unset bits -- reinterpret_cast<void*>(0) -- and that only loads/stores/calls/etc on the former are undefined behaviour, as there may be architectures or programming levels on which referring to memory address 0 is perfectly reasonable. Does C99 have such a distinction as well? ~ Scott