digitalmars.D - Undefined behaviors & Clang 3.3
- bearophile (19/22) Jun 20 2013 Another nice post about the Integer Undefined Behavior Detection
- Paulo Pinto (7/29) Jun 20 2013 I also advise those with Apple accounts to have a look at the
- qznc (7/29) Jun 21 2013 In D an integer overflow is defined, so there is no need to
- bearophile (6/8) Jun 21 2013 A language should offer the programmer a way to specify when an
- eles (7/13) Jun 21 2013 I just wanted to say almost the same thing: that the original
- Artur Skawina (11/24) Jun 21 2013 Actually, it's the other way around - mandating wrapping is what makes i...
- eles (3/8) Jun 21 2013 Very much aware of that. However, going from undefined to (badly)
- qznc (5/20) Jun 21 2013 The D definition mirrors what modern PC architectures do and
- deadalnix (6/10) Jun 21 2013 Some used to have +0 and -0 and so wrapping around do not work.
- Walter Bright (8/12) Jun 21 2013 C is a very old language, and supported many architectures that no longe...
- eles (14/20) Jun 21 2013 First, it is not just about UNDEFINED behaviour, but also about
- Simen Kjaeraas (9/10) Jun 22 2013 Because that's how the hardware works. IEEE-754 floats have special valu...
- eles (3/9) Jun 24 2013 They would never carry when wrapping up if that would have been
- renoX (6/7) Jun 25 2013 The MIPS has instructions which trap on integer overflow (it has
- Artur Skawina (20/24) Jun 21 2013 Keep in mind that this is not necessarily how real compilers treat it:
Another nice post about the Integer Undefined Behavior Detection of Clang 3.3: http://blog.regehr.org/archives/963Until these languages die, which isn’t going to happen anytime soon, our best defense against undefined behaviors is to write better checking tools.<Some potential bugs it has found: http://article.gmane.org/gmane.comp.fonts.freetype.devel/8817 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57324 http://blog.regehr.org/extra_files/perl-test-output.txt Things like this in gcc: gcc/gcc/simplify-rtx.c:4004:16: runtime error: signed integer overflow: -1844674407370955161 + -9223372036854775808 cannot be represented in type 'long' gcc/gcc/stor-layout.c:2543:45: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long' Is someone able to compile and run the dmd source code with Clang with "-fsanitize=undefined"? And is it possible to add -fsanitize=undefined to ldc2? Bye, bearophile
Jun 20 2013
On Thursday, 20 June 2013 at 14:28:42 UTC, bearophile wrote:Another nice post about the Integer Undefined Behavior Detection of Clang 3.3: http://blog.regehr.org/archives/963I also advise those with Apple accounts to have a look at the WWDC 2013 videos, there are a few sessions about LLVM optimizations and auto-vectorization in Clang. Maybe those features could benefit LDC as well. -- PauloUntil these languages die, which isn’t going to happen anytime soon, our best defense against undefined behaviors is to write better checking tools.<Some potential bugs it has found: http://article.gmane.org/gmane.comp.fonts.freetype.devel/8817 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57324 http://blog.regehr.org/extra_files/perl-test-output.txt Things like this in gcc: gcc/gcc/simplify-rtx.c:4004:16: runtime error: signed integer overflow: -1844674407370955161 + -9223372036854775808 cannot be represented in type 'long' gcc/gcc/stor-layout.c:2543:45: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long' Is someone able to compile and run the dmd source code with Clang with "-fsanitize=undefined"? And is it possible to add -fsanitize=undefined to ldc2? Bye, bearophile
Jun 20 2013
On Thursday, 20 June 2013 at 14:28:42 UTC, bearophile wrote:Another nice post about the Integer Undefined Behavior Detection of Clang 3.3: http://blog.regehr.org/archives/963In D an integer overflow is defined, so there is no need to detect anything about it. See Spec: "If both operands are of integral types and an overflow or underflow occurs in the computation, wrapping will happen. That is, uint.max + 1 == uint.min and uint.min - 1 == uint.max." http://dlang.org/expression.htmlUntil these languages die, which isn’t going to happen anytime soon, our best defense against undefined behaviors is to write better checking tools.<Some potential bugs it has found: http://article.gmane.org/gmane.comp.fonts.freetype.devel/8817 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57324 http://blog.regehr.org/extra_files/perl-test-output.txt Things like this in gcc: gcc/gcc/simplify-rtx.c:4004:16: runtime error: signed integer overflow: -1844674407370955161 + -9223372036854775808 cannot be represented in type 'long' gcc/gcc/stor-layout.c:2543:45: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long' Is someone able to compile and run the dmd source code with Clang with "-fsanitize=undefined"? And is it possible to add -fsanitize=undefined to ldc2? Bye, bearophile
Jun 21 2013
qznc:In D an integer overflow is defined, so there is no need to detect anything about it.A language should offer the programmer a way to specify when an integral overflow is acceptable. Otherwise the other cases are bugs. Clang 3.3 helps find some of those bugs. Bye, bearophile
Jun 21 2013
On Friday, 21 June 2013 at 10:42:32 UTC, bearophile wrote:qznc:I just wanted to say almost the same thing: that the original sentence should read: "In D an integer overflow is *badly or, at least, questionably and inflexibly* defined, so there is no *possibility* to detect anything *useful* about it." Well, that was the flame for today.In D an integer overflow is defined, so there is no need to detect anything about it.A language should offer the programmer a way to specify when an integral overflow is acceptable. Otherwise the other cases are bugs. Clang 3.3 helps find some of those bugs.
Jun 21 2013
On 06/21/13 15:48, eles wrote:On Friday, 21 June 2013 at 10:42:32 UTC, bearophile wrote:Actually, it's the other way around - mandating wrapping is what makes it possible for code to detect the overflow. Having overflow be undefined (C-like) means that the compiler as allowed to remove all code that checks for or relies on the overflow happening. Mandating /trapping/ on OF would be a bad idea for perf reasons, You can implement both trapping and saturating arithmetic on top of wrapping. As the people wanting these will either a) don't really care about bare metal performance or a) use h/w acceleration (simd etc) anyway, it isn't really a problem. arturqznc:I just wanted to say almost the same thing: that the original sentence should read: "In D an integer overflow is *badly or, at least, questionably and inflexibly* defined, so there is no *possibility* to detect anything *useful* about it." Well, that was the flame for today.In D an integer overflow is defined, so there is no need to detect anything about it.A language should offer the programmer a way to specify when an integral overflow is acceptable. Otherwise the other cases are bugs. Clang 3.3 helps find some of those bugs.
Jun 21 2013
On Friday, 21 June 2013 at 14:48:46 UTC, Artur Skawina wrote:On 06/21/13 15:48, eles wrote:Very much aware of that. However, going from undefined to (badly) defined is not the best choice, as long as better is available.On Friday, 21 June 2013 at 10:42:32 UTC, bearophile wrote:Actually, it's the other way around - mandating wrapping is what makes it possible for code to detect the overflow. Having overflow be
Jun 21 2013
On Friday, 21 June 2013 at 13:48:19 UTC, eles wrote:On Friday, 21 June 2013 at 10:42:32 UTC, bearophile wrote:The D definition mirrors what modern PC architectures do and hence can be compiled efficiently there. C avoids coupling with any architecture hence "undefined". What architectures do not wrap around?qznc:I just wanted to say almost the same thing: that the original sentence should read: "In D an integer overflow is *badly or, at least, questionably and inflexibly* defined, so there is no *possibility* to detect anything *useful* about it." Well, that was the flame for today.In D an integer overflow is defined, so there is no need to detect anything about it.A language should offer the programmer a way to specify when an integral overflow is acceptable. Otherwise the other cases are bugs. Clang 3.3 helps find some of those bugs.
Jun 21 2013
On Friday, 21 June 2013 at 15:51:55 UTC, qznc wrote:The D definition mirrors what modern PC architectures do and hence can be compiled efficiently there. C avoids coupling with any architecture hence "undefined". What architectures do not wrap around?Some used to have +0 and -0 and so wrapping around do not work. But this didn't survived (or maybe in some exotic not heavily used chips). Similarly, some arch used to use different values than 0 for null. I don't know any modern one that does it.
Jun 21 2013
On 6/21/2013 8:51 AM, qznc wrote:The D definition mirrors what modern PC architectures do and hence can be compiled efficiently there. C avoids coupling with any architecture hence "undefined". What architectures do not wrap around?C is a very old language, and supported many architectures that no longer exist, such as ones-complement machines, machines with 10 bit bytes, weird floating point formats, EBCDIC, 16 bit CPUs, etc. A lot of C code tries to be "portable" to all these no-longer-existing machines, and a lot of effort is wasted. But D has the luxury of taking advantage of the fact that things have converged on 2s-complement, IEEE 754 floating point, 8 bit bytes, Unicode, etc. This means we can now nail down many implementation-defined and undefined behaviors.
Jun 21 2013
On Friday, 21 June 2013 at 15:51:55 UTC, qznc wrote:On Friday, 21 June 2013 at 13:48:19 UTC, eles wrote:First, it is not just about UNDEFINED behaviour, but also about DESIRED behaviur. C's arrays seen as pointers were efficient (and mirroring the architecture who kne nothing about arrays, just about addresses, that is pointers), still D abandoned them for a good reason. Efficiency vs better is a sensible trade-off. Secondly, is just enabling that overflow behavior if chasing a bug, explicitely, with a compiler flag. Use it only if you care. Although the best solution, in my eyes, is to have both wrapping and overfloing signed and unsigned integer types. Chose what you want.On Friday, 21 June 2013 at 10:42:32 UTC, bearophile wrote:The D definition mirrors what modern PC architectures do and hence can be compiled efficiently there. C avoids coupling with any architecture hence "undefined".What architectures do not wrap around?They wrap, but they carry. BTW, floats do not wrap, why integers should behave otherwise?
Jun 21 2013
On Sat, 22 Jun 2013 02:14:18 +0200, eles <eles eles.com> wrote:BTW, floats do not wrap, why integers should behave otherwise?Because that's how the hardware works. IEEE-754 floats have special values that do not behave like other numbers: infinity and nan. The ints the hardware supports have no such thing. Of course, one could write a complex wrapper around the int to get infinity in there, and even nan if one really wanted, but that'd be a lot less efficient, and contrary to how people expect things to work. -- Simen
Jun 22 2013
On Saturday, 22 June 2013 at 07:59:05 UTC, Simen Kjaeraas wrote:On Sat, 22 Jun 2013 02:14:18 +0200, eles <eles eles.com> wrote: Of course, one could write a complex wrapper around the int to get infinity in there, and even nan if one really wanted, but that'd be a lot less efficient, and contrary to how people expect things to work.They would never carry when wrapping up if that would have been the case.
Jun 24 2013
On Friday, 21 June 2013 at 15:51:55 UTC, qznc wrote:What architectures do not wrap around?The MIPS has instructions which trap on integer overflow (it has other which wrap too). Unfortunately, this is the only CPU I know where you can have a sane integer semantic "for free". renoX
Jun 25 2013
On 06/21/13 10:20, qznc wrote:In D an integer overflow is defined, so there is no need to detect anything about it. See Spec: "If both operands are of integral types and an overflow or underflow occurs in the computation, wrapping will happen. That is, uint.max + 1 == uint.min and uint.min - 1 == uint.max." http://dlang.org/expression.htmlKeep in mind that this is not necessarily how real compilers treat it: void main() { auto a = int.max; if (a+1<a.max) assert(0); } will not assert when compiled with gdc; you'd have to explicitly disable that optimization. GCC statically evaluates this kind of checks, by assuming that signed overflow can't happen - because it's undefined. But that's not true for D, so, until the compiler is fixed, the '-fno-strict-overflow' compiler flag has to be used if "spec"-like behaviour is desired. Requiring wrapping arithmetic removes some opportunities for optimization, hence should, ideally, be complemented by more value range awareness in the language. D doesn't really have the latter, so right now, avoiding the UB in these cases has a cost. Still, GDC should just be fixed, as having a subtly different dialect is worse. Right now, incorrect (according to the "spec") code is silently generated, causing data corruption. artur
Jun 21 2013