5682 – Silently wrong CTFE result possibly related to operator overloading and expression order

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5682 - Silently wrong CTFE result possibly related to operator overloading and expression order
Summary: Silently wrong CTFE result possibly related to operator overloading and expre...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Mac OS X
: P2 critical
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
Reported: 2011年03月02日 12:50 UTC by David Nadlinger
Modified: 2011年05月18日 21:19 UTC (History)
1 user (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description David Nadlinger 2011年03月02日 12:50:58 UTC
The test function below will produce different results depending on whether it is executed normally or via CTFE with latest DMD (git master at a47637b0):
---
import std.stdio;
struct A {
 int n;
 auto opBinary(string op : "*")(A rhs) {
 return A(n * rhs.n);
 }
}
A foo(A[] lhs, A[] rhs) {
 A current;
 for (size_t k = 0; k < rhs.length; ++k) {
 current = lhs[k] * rhs[k]; // This is the crucial line.
 }
 return current;
}
auto test() {
 return foo([A(1), A(2)], [A(3), A(4)]);
}
void main() {
 enum tc = test();
 writefln("compile-time: %s; run-time: %s", tc.n, test().n);
}
---
compile-time: 4; run-time: 8
---
A few observations:
 - At compile-time, the first element from the first factor (lhs[0]) seems to be read twice, replacing A(2) with another value doesn't change the CTFE result.
 - Swapping lhs[k] and rhs[k] will change the CTFE result to 6 (supporting the above assumption).
 - If foo() is modified to work on e.g. int instead of A values, the problem doesn't occur.
 - If the assignment in question is replaced with »A a1 = lhs[k]; A a2 = rhs[k]; current = a1 * a2;«, the bug does not longer occur.


AltStyle によって変換されたページ (->オリジナル) /