Issue #7371 has been reported by xi (Xi Wang). ---------------------------------------- Bug #7371: Fix undefined overflow checking in bigdecimal https://bugs.ruby-lang.org/issues/7371 Author: xi (Xi Wang) Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: 1.9.x In AddExponent() at ext/bigdecimal/bigdecimal.c:3677, the overflow checks rely on signed integer overflow, which is undefined behavior in C. SIGNED_VALUE m = e+n; SIGNED_VALUE eb, mb; if(e>0) { if(n>0) { mb = m*(SIGNED_VALUE)BASE_FIG; eb = e*(SIGNED_VALUE)BASE_FIG; if(mb<eb) goto overflow; } Some compilers (e.g., gcc 4.8) will optimize away such overflow checks due to undefined behavior. Ruby currently uses "-fno-strict-overflow" to disable such offending optimizations in gcc, but this workaround option is not supported by other compilers, thus not portable. The attached patch uses unsigned multiplication for overflow checking, which is well defined in C.
on 2012-11-16 09:24
on 2012-11-17 04:11
Issue #7371 has been updated by mrkn (Kenta Murata). Category set to ext Assignee set to mrkn (Kenta Murata) ---------------------------------------- Bug #7371: Fix undefined overflow checking in bigdecimal https://bugs.ruby-lang.org/issues/7371#change-33009 Author: xi (Xi Wang) Status: Open Priority: Normal Assignee: mrkn (Kenta Murata) Category: ext Target version: ruby -v: 1.9.x In AddExponent() at ext/bigdecimal/bigdecimal.c:3677, the overflow checks rely on signed integer overflow, which is undefined behavior in C. SIGNED_VALUE m = e+n; SIGNED_VALUE eb, mb; if(e>0) { if(n>0) { mb = m*(SIGNED_VALUE)BASE_FIG; eb = e*(SIGNED_VALUE)BASE_FIG; if(mb<eb) goto overflow; } Some compilers (e.g., gcc 4.8) will optimize away such overflow checks due to undefined behavior. Ruby currently uses "-fno-strict-overflow" to disable such offending optimizations in gcc, but this workaround option is not supported by other compilers, thus not portable. The attached patch uses unsigned multiplication for overflow checking, which is well defined in C.
on 2012-12-21 14:19
Issue #7371 has been updated by usa (Usaku NAKAMURA). Status changed from Open to Assigned ---------------------------------------- Bug #7371: Fix undefined overflow checking in bigdecimal https://bugs.ruby-lang.org/issues/7371#change-34941 Author: xi (Xi Wang) Status: Assigned Priority: Normal Assignee: mrkn (Kenta Murata) Category: ext Target version: ruby -v: 1.9.x In AddExponent() at ext/bigdecimal/bigdecimal.c:3677, the overflow checks rely on signed integer overflow, which is undefined behavior in C. SIGNED_VALUE m = e+n; SIGNED_VALUE eb, mb; if(e>0) { if(n>0) { mb = m*(SIGNED_VALUE)BASE_FIG; eb = e*(SIGNED_VALUE)BASE_FIG; if(mb<eb) goto overflow; } Some compilers (e.g., gcc 4.8) will optimize away such overflow checks due to undefined behavior. Ruby currently uses "-fno-strict-overflow" to disable such offending optimizations in gcc, but this workaround option is not supported by other compilers, thus not portable. The attached patch uses unsigned multiplication for overflow checking, which is well defined in C.
on 2012-12-31 06:02
Issue #7371 has been updated by xi (Xi Wang).
To see how it works, try to compile the following (simplified) code with
gcc 4.8. The entire function will be optimized away with "gcc -O2"
(just grep "bar" in the resulting assembly code); gcc 4.7 or earlier
doesn't do that.
#define SIGNED_VALUE long
#define BASE_FIG 9
void bar(void);
static void AddExponent(SIGNED_VALUE e, SIGNED_VALUE n)
{
SIGNED_VALUE m = e+n;
SIGNED_VALUE eb, mb;
if(e>0) {
if(n>0) {
mb = m*(SIGNED_VALUE)BASE_FIG;
eb = e*(SIGNED_VALUE)BASE_FIG;
if(mb<eb) goto overflow;
}
}
return;
overflow:
bar();
}
void foo(SIGNED_VALUE e)
{
AddExponent(e, 1);
}
----------------------------------------
Bug #7371: Fix undefined overflow checking in bigdecimal
https://bugs.ruby-lang.org/issues/7371#change-35165
Author: xi (Xi Wang)
Status: Assigned
Priority: Normal
Assignee: mrkn (Kenta Murata)
Category: ext
Target version:
ruby -v: 1.9.x
In AddExponent() at ext/bigdecimal/bigdecimal.c:3677, the overflow
checks rely on signed integer overflow, which is undefined behavior in
C.
SIGNED_VALUE m = e+n;
SIGNED_VALUE eb, mb;
if(e>0) {
if(n>0) {
mb = m*(SIGNED_VALUE)BASE_FIG;
eb = e*(SIGNED_VALUE)BASE_FIG;
if(mb<eb) goto overflow;
}
Some compilers (e.g., gcc 4.8) will optimize away such overflow checks
due to undefined behavior. Ruby currently uses "-fno-strict-overflow"
to disable such offending optimizations in gcc, but this workaround
option is not supported by other compilers, thus not portable.
The attached patch uses unsigned multiplication for overflow checking,
which is well defined in C.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.