[llvm-dev] Calling a null pointer. How undefined it is?

David Chisnall via llvm-dev llvm-dev at lists.llvm.org
Tue Jun 14 06:23:48 PDT 2016


On 14 Jun 2016, at 14:21, Gor Nishanov via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> You are right. After thinking a bit more, reading your reply and
> re-reading llvm blog post on undefined behavior, I realized, duh,
> that even on systems where NULL access results in a crash we can
> still get into a bad situation.
> 
>  struct State {
>     FnPtr Fn;
>     State() : Fn(&SomeFunction) {}
> 
>     void Go() { (*Fn)(); } // may be devirtualized to SomeFunction()
>     void Stop() { Fn = nullptr; }
>     bool IsDone() { return Fn == nullptr; }
>   };
> 
> Since, calling Go() when the state machine has reached the "Done"
> state is undefined, it is perfectly legal to replace an indirect
> call with direct call to its target. Thus, if the user end up
> calling Go() in a done state, it won't crash, but, invoke SomeFunction()
> which may do some bad things since we are no longer in a valid state.

It seems that you could easily achieve what you want by replacing nullptr with abort in this example.  IsDone would be slightly more expensive (compare address of a global to Fn, rather than 0), but I doubt you’d be able to measure the difference in most code.

David



More information about the llvm-dev mailing list