diff -r e3c851a14f16 -r 18f3010a358c src/compiler/SemanticAnalysis.cpp --- a/src/compiler/SemanticAnalysis.cpp Tue Dec 25 18:13:02 2012 -0800 +++ b/src/compiler/SemanticAnalysis.cpp Wed Dec 26 17:14:12 2012 -0800 @@ -731,6 +731,11 @@ if (!lval) return; + if (lval->type()->quals() & TypeQual_Const) { + cc_.reportError(node->pos(), Message_CannotModifyConst); + return; + } + HIR *hir = eval(node->expression()); if ((hir = coerce(hir, lval->type(), Coerce_Assign)) == NULL) return; @@ -838,7 +843,7 @@ HIR * SemanticAnalysis::typeCheckArray(const SourcePosition &pos, HIR *from, - Handle argActual, + Handle argActual, CoercionKind kind) { Local argGiven(zone_, from->type()); @@ -888,7 +893,7 @@ // We treat declaration separately from assignment, since for // declaration we can just immediately use the cloned version. bool shouldDuplicate = true; - if (0 /*actual->isConst() :TODO */ || + if ((actual->quals() & TypeQual_Const) || (actual->isFixedLength() && kind == Coerce_Assign)) { shouldDuplicate = false; @@ -959,11 +964,18 @@ actual = ArrayType::cast(actual->contained()); } + bool givenConst = !!(given->contained()->quals() & TypeQual_Const); + bool actualConst = !!(actual->contained()->quals() & TypeQual_Const); + // These arrays must contain the same innermost type. - if (given->contained() != actual->contained()) { + if (given->contained()->unqualified() != actual->contained()->unqualified() || + (givenConst && !actualConst)) + { + char aname[255]; + char gname[255]; cc_.reportError(pos, Message_TypeMismatch, - GetTypeName(actual->contained()), - GetTypeName(given->contained())); + GetTypeName(argActual, aname, sizeof(aname)), + GetTypeName(argGiven, gname, sizeof(gname))); return false; } @@ -973,9 +985,11 @@ HIR * SemanticAnalysis::typeFailure(const SourcePosition &pos, Handle from, Handle to) { + char fname[255]; + char tname[255]; cc_.reportError(pos, Message_InvalidCoercion, - GetTypeName(from), - GetTypeName(to)); + GetTypeName(from, fname, sizeof(fname)), + GetTypeName(to, tname, sizeof(tname))); return NULL; } @@ -992,8 +1006,10 @@ if (to->isEnum() && *from != to) return typeFailure(hir->node()->pos(), from, to); - if (to->isArray()) - return typeCheckArray(SourcePosition(), hir, to, kind); + if (to->isArray()) { + Local atype(zone_, ArrayType::cast(to)); + return typeCheckArray(hir->node()->pos(), hir, atype, kind); + } return hir; }