3059 – Nonsensical complex op= should be illegal

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3059 - Nonsensical complex op= should be illegal
Summary: Nonsensical complex op= should be illegal
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: All All
: P2 normal
Assignee: Walter Bright
URL:
Keywords: accepts-invalid, patch
Depends on:
Blocks:
Reported: 2009年06月09日 16:33 UTC by Don
Modified: 2014年02月15日 13:12 UTC (History)
0 users

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 Don 2009年06月09日 16:33:48 UTC
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);
 }
Comment 1 Walter Bright 2009年10月06日 02:16:56 UTC
Fixed dmd 1.048 and 2.033


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