Thread overview
Found by Coverty in LibreOffice
Nov 10, 2014
bearophile
Nov 10, 2014
Rikki Cattermole
Nov 10, 2014
Rikki Cattermole
Nov 10, 2014
John Colvin
Nov 10, 2014
bearophile
Nov 11, 2014
Meta
November 10, 2014
Some of the bugs that the static analysis tool Coverty has found in the C++ code of LibreOffice:

http://cgit.freedesktop.org/libreoffice/core/log/?qt=grep&q=coverity


Cases like this remind me that division operator shouldn't accept a divisor of generic integer/floating/multi-precision type, but a type that lacks a zero:

http://cgit.freedesktop.org/libreoffice/core/commit/?id=4a83b67e3c3dc8bceb6602ce155f2463f72f4855

http://cgit.freedesktop.org/libreoffice/core/commit/?id=7ca34b04c0915cb00345afa1ba7cfc736f82f9a1

http://cgit.freedesktop.org/libreoffice/core/commit/?id=c61b2066660fb0130f0b0f9f51b48e3799625b83

Bye,
bearophile
November 10, 2014
On 10/11/2014 11:04 p.m., bearophile wrote:
> Some of the bugs that the static analysis tool Coverty has found in the
> C++ code of LibreOffice:
>
> http://cgit.freedesktop.org/libreoffice/core/log/?qt=grep&q=coverity
>
>
> Cases like this remind me that division operator shouldn't accept a
> divisor of generic integer/floating/multi-precision type, but a type
> that lacks a zero:
>
> http://cgit.freedesktop.org/libreoffice/core/commit/?id=4a83b67e3c3dc8bceb6602ce155f2463f72f4855
>
>
> http://cgit.freedesktop.org/libreoffice/core/commit/?id=7ca34b04c0915cb00345afa1ba7cfc736f82f9a1
>
>
> http://cgit.freedesktop.org/libreoffice/core/commit/?id=c61b2066660fb0130f0b0f9f51b48e3799625b83
>
>
> Bye,
> bearophile

Interesting.
Code like this could be rather interesting.

alias NonZero = AbituaryRestriction!("value == 0", "Value cannot be 0");
template AbituaryRestriction(string restriction, string reason) {
	struct AbituaryRestriction(T) {
		T value;
		alias value this;
	
		this(T value) {
			this.value = value;
		}
		
		invariant() {
			if (mixin(restriction)) {
				throw new Exception(reason);	
			}
		}
		
		void opAssign(float value) {
			this.value = value;	
		}
	}
}

void main() {
	NonZero!float ft = 0.5f;
	ft = 0;
}
November 10, 2014
On 10/11/2014 11:23 p.m., Rikki Cattermole wrote:
> On 10/11/2014 11:04 p.m., bearophile wrote:
>> Some of the bugs that the static analysis tool Coverty has found in the
>> C++ code of LibreOffice:
>>
>> http://cgit.freedesktop.org/libreoffice/core/log/?qt=grep&q=coverity
>>
>>
>> Cases like this remind me that division operator shouldn't accept a
>> divisor of generic integer/floating/multi-precision type, but a type
>> that lacks a zero:
>>
>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=4a83b67e3c3dc8bceb6602ce155f2463f72f4855
>>
>>
>>
>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=7ca34b04c0915cb00345afa1ba7cfc736f82f9a1
>>
>>
>>
>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=c61b2066660fb0130f0b0f9f51b48e3799625b83
>>
>>
>>
>> Bye,
>> bearophile
>
> Interesting.
> Code like this could be rather interesting.
>
> alias NonZero = AbituaryRestriction!("value == 0", "Value cannot be 0");
> template AbituaryRestriction(string restriction, string reason) {
>      struct AbituaryRestriction(T) {
>          T value;
>          alias value this;
>
>          this(T value) {
>              this.value = value;
>          }
>
>          invariant() {
>              if (mixin(restriction)) {
>                  throw new Exception(reason);
>              }
>          }
>
>          void opAssign(float value) {

Looks like I didn't quite catch all those float's during testing. Woops (should be T instead of float).

>              this.value = value;
>          }
>      }
> }
>
> void main() {
>      NonZero!float ft = 0.5f;
>      ft = 0;
> }

November 10, 2014
On Monday, 10 November 2014 at 10:23:09 UTC, Rikki Cattermole wrote:
> On 10/11/2014 11:04 p.m., bearophile wrote:
>> Some of the bugs that the static analysis tool Coverty has found in the
>> C++ code of LibreOffice:
>>
>> http://cgit.freedesktop.org/libreoffice/core/log/?qt=grep&q=coverity
>>
>>
>> Cases like this remind me that division operator shouldn't accept a
>> divisor of generic integer/floating/multi-precision type, but a type
>> that lacks a zero:
>>
>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=4a83b67e3c3dc8bceb6602ce155f2463f72f4855
>>
>>
>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=7ca34b04c0915cb00345afa1ba7cfc736f82f9a1
>>
>>
>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=c61b2066660fb0130f0b0f9f51b48e3799625b83
>>
>>
>> Bye,
>> bearophile
>
> Interesting.
> Code like this could be rather interesting.
>
> alias NonZero = AbituaryRestriction!("value == 0", "Value cannot be 0");
> template AbituaryRestriction(string restriction, string reason) {
> 	struct AbituaryRestriction(T) {
> 		T value;
> 		alias value this;
> 	
> 		this(T value) {
> 			this.value = value;
> 		}
> 		
> 		invariant() {
> 			if (mixin(restriction)) {
> 				throw new Exception(reason);	
> 			}
> 		}
> 		
> 		void opAssign(float value) {
> 			this.value = value;	
> 		}
> 	}
> }
>
> void main() {
> 	NonZero!float ft = 0.5f;
> 	ft = 0;
> }

you mean arbitrary, right?
November 10, 2014
Rikki Cattermole:

>> Cases like this remind me that division operator shouldn't accept a divisor of generic integer/floating/multi-precision
>> type, but a type that lacks a zero:
> ...
> Interesting.
> Code like this could be rather interesting.

In an old language like Ada you have to use explicitly a type that doesn't contain a zero (like a 1..5 range, or a natural, etc). But in a more modern language you can use "flow typing" (as seen in the Whiley language and elsewhere), so code similar to this (in D-like language) compiles:


int foo(in uint x, in uint y) {
    if (y == 0)
        throw new Exception("Bad");
    else {
        static assert(is(typeof(y) == Natural));
        return x / y;
    }
}

In Whiley inside the else branch the _type_ of y is different.

Bye,
bearophile
November 11, 2014
You might find this interesting:

http://forum.dlang.org/post/mailman.43.1385384503.3242.digitalmars-d@puremagic.com