[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