Peter Lawrence via llvm-dev
2017-Jun-16 14:33 UTC
[llvm-dev] function inlining and undef / poison question
John, the program below is not necessarily *undefined* in the C programming sense, the C89 and C99 standards say the value of a stack auto variable that is not initialized is “indeterminate”, not “undefined behavior”, it then goes on to say that “indeterminate” is either “unspecified” or “trap representation”. The standard absolutely does not require this to be “UB”, and making it so in llvm is wrong, it leads to unexpected and unwanted transformations that are indefensible from the users point of view. Peter Lawrence. C89, see section 6.5.7 Initialization. If an object that has automatic storage duration is not initialized explicitely, its value is indeterminate. If an object that has static storage duration is not initialized explicitely, it is initialized implicitely as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant. C99, see section 6.7.8 Initialization. If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then: — if it has pointer type, it is initialized to a null pointer; — if it has arithmetic type, it is initialized to (positive or unsigned) zero; — if it is an aggregate, every member is initialized (recursively) according to these rules; — if it is a union, the first named member is initialized (recursively) according to these rules. C89, C99 see section 3.17.2 indeterminate value either an unspecified value or a trap representation> > Date: Thu, 15 Jun 2017 17:35:55 -0600 > From: John Regehr via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> > To: llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > Subject: Re: [llvm-dev] Function Inlining and undef / poison question > >> void F(int a) >> { >> if (a == a) do_stuff(); >> } >> >> .... >> main() >> { >> int x; >> F(x); >> } > > This C program unconditionally executes UB and any translation at all is > acceptable -- end of story. > > John >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170616/67b790ee/attachment.html>
John Regehr via llvm-dev
2017-Jun-16 15:12 UTC
[llvm-dev] function inlining and undef / poison question
Trap representations are primarily just a funny way to say undefined behavior, see 6.2.6.1 p5 of C99: "Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined. Such a representation is called a trap representation." Here's a reasonable discussion of the issues surrounding uninitialized storage: http://queue.acm.org/detail.cfm?id=3041020 This is definitely a sucky part of the standards and I hope they manage to clear it up. However, none of this causes problems for us at the LLVM level. Whatever it is that reading uninitialized storage means (and I am uninterested in debating this further, at least on this list), we almost certainly have a mechanism for expressing that in LLVM. Thus, as far as I can tell, there is no problem here. John