src/SemanticAnalysis.cpp
changeset 184 387d76b1e981
parent 183 05571208642f
child 185 10936f3a2ba3
     1.1 --- a/src/SemanticAnalysis.cpp	Sat Sep 15 13:32:01 2012 -0700
     1.2 +++ b/src/SemanticAnalysis.cpp	Sat Sep 15 17:39:45 2012 -0700
     1.3 @@ -717,7 +717,7 @@
     1.4                  return;
     1.5          }
     1.6  
     1.7 -        if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
     1.8 +        if (node->postDimensions()->length() > Type::MAX_ARRAY_DEPTH) {
     1.9              cc_.reportError(node->pos(), Message_MaximumArrayDepth);
    1.10              return;
    1.11          }
    1.12 @@ -756,17 +756,17 @@
    1.13                      }
    1.14  
    1.15                      if (check) {
    1.16 -                        if (check->elements() == -1) {
    1.17 +                        if (!check->isFixedLength()) {
    1.18                              cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
    1.19                              return;
    1.20                          }
    1.21  
    1.22                          if (check->isCharArray()) {
    1.23 -                            if (check->elements() > size) {
    1.24 +                            if (check->fixedLength() > unsigned(size)) {
    1.25                                  cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
    1.26                                  return;
    1.27                              }
    1.28 -                        } else if (check->elements() != size) {
    1.29 +                        } else if (check->fixedLength() != unsigned(size)) {
    1.30                              cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
    1.31                              return;
    1.32                          }
    1.33 @@ -787,11 +787,11 @@
    1.34                      cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
    1.35                      return;
    1.36                  }
    1.37 -                if (init->elements() == -1) {
    1.38 +                if (!init->isFixedLength()) {
    1.39                      cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
    1.40                      return;
    1.41                  }
    1.42 -                size = init->elements();
    1.43 +                size = init->fixedLength();
    1.44              }
    1.45  
    1.46              type = zone_->types()->unsafeArray(type, size, false);
    1.47 @@ -917,7 +917,7 @@
    1.48              if (!type)
    1.49                  return false;
    1.50          } else if (parameter->dimensions()) {
    1.51 -            if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
    1.52 +            if (parameter->dimensions()->length() > Type::MAX_ARRAY_DEPTH) {
    1.53                  cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
    1.54                  return false;
    1.55              }
    1.56 @@ -929,9 +929,9 @@
    1.57  
    1.58              for (size_t i = parameter->dimensions()->length() - 1;
    1.59                   i < parameter->dimensions()->length();
    1.60 -                 i++)
    1.61 +                 i--)
    1.62              {
    1.63 -                int size = Type::UNKNOWN_SIZE;
    1.64 +                int size = Type::DYNAMIC_ARRAY_SIZE;
    1.65                  if (Expression *expr = parameter->dimensions()->at(i)) {
    1.66                      BoxedPrimitive box;
    1.67                      if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
    1.68 @@ -1112,30 +1112,44 @@
    1.69  
    1.70      unsigned level = 1;
    1.71      while (given->isArray()) {
    1.72 -        if (actual->elements() != -1) {
    1.73 +        if (actual->isFixedLength()) {
    1.74              if (forAssign) {
    1.75 -                if (given->elements() == -1 || actual->elements() == -1) {
    1.76 -                    cc_.reportError(pos, Message_ArraySizeNotKnown);
    1.77 +                if (!given->isFixedLength()) {
    1.78 +                    cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
    1.79                      return false;
    1.80                  }
    1.81  
    1.82                  if (actual->isCharArray()) {
    1.83                      // String assignment can have a truncated |given|.
    1.84 -                    if (given->elements() > actual->elements()) {
    1.85 +                    if (given->fixedLength() > actual->fixedLength()) {
    1.86                          cc_.reportError(pos, Message_ArrayAssignmentTooBig);
    1.87                          return false;
    1.88                      }
    1.89                  } else {
    1.90 -                    if (given->elements() != actual->elements()) {
    1.91 +                    if (given->fixedLength() != actual->fixedLength()) {
    1.92                          cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
    1.93                          return false;
    1.94                      }
    1.95                  }
    1.96 -            } else {
    1.97 -                if (actual->elements() != -1 && given->elements() != actual->elements()) {
    1.98 -                    cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
    1.99 -                    return false;
   1.100 -                }
   1.101 +            }
   1.102 +        } else if (given->isFixedLength()) {
   1.103 +            // We do not allow assignments in the form:
   1.104 +            //    [][] = [X][Y]
   1.105 +            //
   1.106 +            // Otherwise, the following code could break the size guarantees
   1.107 +            // of the right-hand side:
   1.108 +            //
   1.109 +            //   new x[][5];
   1.110 +            //   new y[][];
   1.111 +            //   new z[3];
   1.112 +            //
   1.113 +            //   y = x;
   1.114 +            //   y[0] = z;
   1.115 +            //   
   1.116 +            // Now |x[0]| contains a 4-length array.
   1.117 +            if (level > 1) {
   1.118 +                cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
   1.119 +                return false;
   1.120              }
   1.121          }
   1.122          given = given->contained();