[Issue 3059] New: Nonsensical complex op= should be illegal
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Jun 9 16:33:49 PDT 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3059
Summary: Nonsensical complex op= should be illegal
Product: D
Version: 1.00
Platform: All
OS/Version: All
Status: NEW
Keywords: accepts-invalid, patch
Severity: normal
Priority: P2
Component: DMD
AssignedTo: bugzilla at digitalmars.com
ReportedBy: clugdbug at yahoo.com.au
All operations A op= B, where A is real or imaginary and A op B is complex,
should be illegal, as they are mathematically nonsensical. Sending these
operations to the back-end is responsible for at least two internal compiler
errors.
The operations +=, -=, *=, /=, and %= are all affected. Applies to both D1 and
D2.
TEST CASE:
void main() {
ireal x = 3.0i;
double y=3;
y /= 2.0 + 6i;
x *= 7.0i;
x *= 3.0i+2;
x %= (2+ 6.0i);
x += 2.0;
x -= 1+4i;
y -= 3.0i;
}
Patch (expression.c):
This patch fixes makes the nonsensical operations illegal.
Where possible, the error message suggests an alternative.
This also fixes two ICE bugs: bug 718 and bug 2839.
=====================
@@ -8313,6 +8340,35 @@
return this;
}
+// generate an error if this is a nonsensical *=,/=, or %=, eg real *=
imaginary
+void checkComplexMulAssign(char *opstr, Loc loc, Expression *e1, Expression
*e2) {
+ // Any multiplication by an imaginary or complex number yields a complex
result.
+ // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
+ if ( e1->type->isreal() && e2->type->iscomplex()) {
+ error(loc, "%s %s= %s is undefined. Did you mean %s %s= %s.re ?",
+ e1->type->toChars(), opstr, e2->type->toChars(),
+ e1->type->toChars(), opstr, e2->type->toChars());
+ } else if (e1->type->isimaginary() && e2->type->iscomplex()) {
+ error(loc, "%s %s= %s is undefined. Did you mean %s %s= %s.im ?",
+ e1->type->toChars(), opstr, e2->type->toChars(),
+ e1->type->toChars(), opstr, e2->type->toChars());
+ } else if ((e1->type->isreal() || e1->type->isimaginary()) &&
e2->type->isimaginary()) {
+ error(loc, "%s %s= %s is an undefined operation", e1->type->toChars(),
opstr, e2->type->toChars());
+ }
+}
+
+// generate an error if this is a nonsensical += or -=, eg real += imaginary
+void checkComplexAddAssign(char *opstr, Loc loc, Expression *e1, Expression
*e2) {
+ // Addition or subtraction of a real and an imaginary is a complex result.
+ // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
+ if ( (e1->type->isreal() && (e2->type->isimaginary() ||
e2->type->iscomplex())) ||
+ (e1->type->isimaginary() && (e2->type->isreal() ||
e2->type->iscomplex()))
+ ) {
+ error(loc, "%s %s= %s is undefined (result is complex)",
e1->type->toChars(), opstr, e2->type->toChars());
+ }
+}
+
+
AddAssignExp::AddAssignExp(Loc loc, Expression *e1, Expression *e2)
@@ -8408,6 +8472,7 @@
typeCombine(sc);
e1->checkArithmetic();
e2->checkArithmetic();
+ checkComplexAddAssign("+", loc, e1, e2);
if (type->isreal() || type->isimaginary())
{
assert(global.errors || e2->type->isfloating());
@@ -8455,6 +8520,7 @@
{
e1 = e1->checkArithmetic();
e2 = e2->checkArithmetic();
+ checkComplexAddAssign("-", loc, e1, e2);
type = e1->type;
typeCombine(sc);
if (type->isreal() || type->isimaginary())
@@ -8556,6 +8622,7 @@
typeCombine(sc);
e1->checkArithmetic();
e2->checkArithmetic();
+ checkComplexMulAssign("*", loc, e1, e2);
if (e2->type->isfloating())
{ Type *t1;
Type *t2;
@@ -8619,6 +8686,7 @@
typeCombine(sc);
e1->checkArithmetic();
e2->checkArithmetic();
+ checkComplexMulAssign("/", loc, e1, e2);
if (e2->type->isimaginary())
{ Type *t1;
Type *t2;
@@ -8662,6 +8730,8 @@
Expression *ModAssignExp::semantic(Scope *sc)
{
+ BinExp::semantic(sc);
+ checkComplexMulAssign("%", loc, e1, e2);
return commonSemanticAssign(sc);
}
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list