diff dmd/expression.c @ 510:6aee82889553

Merged DMD 1.034, array operations are not yet implemented ;)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Thu, 14 Aug 2008 06:55:41 +0200
parents a34078905d01
children f79bbd1d0b27
line wrap: on
line diff
--- a/dmd/expression.c	Thu Aug 14 03:09:26 2008 +0200
+++ b/dmd/expression.c	Thu Aug 14 06:55:41 2008 +0200
@@ -368,6 +368,7 @@
 	{
 	    e->error("expression has no value");
 	}
+
     }
     return e;
 }
@@ -389,6 +390,26 @@
     }
 }
 
+
+/******************************
+ * Perform canThrow() on an array of Expressions.
+ */
+
+#if DMDV2
+int arrayExpressionCanThrow(Expressions *exps)
+{
+    if (exps)
+    {
+	for (size_t i = 0; i < exps->dim; i++)
+	{   Expression *e = (Expression *)exps->data[i];
+	    if (e && e->canThrow())
+		return 1;
+	}
+    }
+    return 0;
+}
+#endif
+
 /****************************************
  * Expand tuples.
  */
@@ -503,10 +524,10 @@
 /****************************************
  * Now that we know the exact type of the function we're calling,
  * the arguments[] need to be adjusted:
- *	1) implicitly convert argument to the corresponding parameter type
- *	2) add default arguments for any missing arguments
- *	3) do default promotions on arguments corresponding to ...
- *	4) add hidden _arguments[] argument
+ *	1. implicitly convert argument to the corresponding parameter type
+ *	2. add default arguments for any missing arguments
+ *	3. do default promotions on arguments corresponding to ...
+ *	4. add hidden _arguments[] argument
  */
 
 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments)
@@ -802,6 +823,7 @@
 Expression::Expression(Loc loc, enum TOK op, int size)
     : loc(loc)
 {
+    //printf("Expression::Expression(op = %d) this = %p\n", op, this);
     this->loc = loc;
     this->op = op;
     this->size = size;
@@ -832,6 +854,7 @@
 	assert(0);
     }
     e = (Expression *)mem.malloc(size);
+    //printf("Expression::copy(op = %d) e = %p\n", op, e);
     return (Expression *)memcpy(e, this, size);
 }
 
@@ -965,6 +988,8 @@
 
 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
 {
+    //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());
+
     // See if this expression is a modifiable lvalue (i.e. not const)
     return toLvalue(sc, e);
 }
@@ -1300,7 +1325,8 @@
 	    type = Type::tint32;
     }
     else
-    {	type = type->semantic(loc, sc);
+    {	if (!type->deco)
+	    type = type->semantic(loc, sc);
     }
     return this;
 }
@@ -1785,7 +1811,8 @@
     {	Expression *e;
 	WithScopeSymbol *withsym;
 
-	// See if it was a with class
+	/* See if the symbol was a member of an enclosing 'with'
+	 */
 	withsym = scopesym->isWithScopeSymbol();
 	if (withsym)
 	{
@@ -1800,7 +1827,7 @@
 	    else
 	    {	Type *t = withsym->withstate->wthis->type;
 		if (t->ty == Tpointer)
-		    t = t->next;
+		    t = ((TypePointer *)t)->next;
 		e = new TypeDotIdExp(loc, t, ident);
 	    }
 	}
@@ -2161,8 +2188,8 @@
     return this;
 
 Lerr:
-    error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars());
-    type = Type::tint32;
+    error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars());
+    type = Type::terror;
     return this;
 }
 
@@ -2695,7 +2722,7 @@
 	    // Convert any static arrays to dynamic arrays
 	    if (t0->ty == Tsarray)
 	    {
-		t0 = t0->next->arrayOf();
+		t0 = ((TypeSArray *)t0)->next->arrayOf();
 		e = e->implicitCastTo(sc, t0);
 	    }
 	}
@@ -2906,6 +2933,8 @@
 #if LOGSEMANTIC
     printf("StructLiteralExp::semantic('%s')\n", toChars());
 #endif
+    if (type)
+	return this;
 
     // Run semantic() on each element
     for (size_t i = 0; i < elements->dim; i++)
@@ -2986,11 +3015,17 @@
  */
 
 Expression *StructLiteralExp::getField(Type *type, unsigned offset)
-{   Expression *e = NULL;
+{
+    //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n",
+//	/*toChars()*/"", type->toChars(), offset);
+    Expression *e = NULL;
     int i = getFieldIndex(type, offset);
 
     if (i != -1)
-    {   e = (Expression *)elements->data[i];
+    {
+	//printf("\ti = %d\n", i);
+	assert(i < elements->dim);
+	e = (Expression *)elements->data[i];
 	if (e)
 	{
 	    e = e->copy();
@@ -3330,7 +3365,7 @@
 	    Dsymbol *s = cd->toParent2();
 	    ClassDeclaration *cdn = s->isClassDeclaration();
 
-	    //printf("isNested, cdn = %s\n", cdn ? cdn->toChars() : "null");
+	    //printf("cd isNested, cdn = %s\n", cdn ? cdn->toChars() : "null");
 	    if (cdn)
 	    {
 		if (!cdthis)
@@ -3485,7 +3520,7 @@
 	    if (arg->op == TOKint64 && (long long)arg->toInteger() < 0)
 		error("negative array index %s", arg->toChars());
 	    arguments->data[i] = (void *) arg;
-	    tb = tb->next->toBasetype();
+	    tb = ((TypeDArray *)tb)->next->toBasetype();
 	}
     }
     else if (tb->isscalar())
@@ -3822,6 +3857,29 @@
 }
 
 
+/******************************** OverExp **************************/
+
+#if DMDV2
+OverExp::OverExp(OverloadSet *s)
+	: Expression(loc, TOKoverloadset, sizeof(OverExp))
+{
+    //printf("OverExp(this = %p, '%s')\n", this, var->toChars());
+    vars = s;
+    type = Type::tvoid;
+}
+
+int OverExp::isLvalue()
+{
+    return 1;
+}
+
+Expression *OverExp::toLvalue(Scope *sc, Expression *e)
+{
+    return this;
+}
+#endif
+
+
 /******************************** TupleExp **************************/
 
 TupleExp::TupleExp(Loc loc, Expressions *exps)
@@ -4158,6 +4216,43 @@
     buf->writeByte(')');
 }
 
+/************************ TraitsExp ************************************/
+#if DMDV2
+/*
+ *	__traits(identifier, args...)
+ */
+
+TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args)
+    : Expression(loc, TOKtraits, sizeof(TraitsExp))
+{
+    this->ident = ident;
+    this->args = args;
+}
+
+
+Expression *TraitsExp::syntaxCopy()
+{
+    return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args));
+}
+
+
+void TraitsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{
+    buf->writestring("__traits(");
+    buf->writestring(ident->toChars());
+    if (args)
+    {
+	for (int i = 0; i < args->dim; i++)
+	{
+	    buf->writeByte(',');
+	    Object *oarg = (Object *)args->data[i];
+	    ObjectToCBuffer(buf, hgs, oarg);
+	}
+    }
+    buf->writeByte(')');
+}
+#endif
+
 /************************************************************/
 
 HaltExp::HaltExp(Loc loc)
@@ -4210,7 +4305,11 @@
 Expression *IsExp::semantic(Scope *sc)
 {   Type *tded;
 
-    //printf("IsExp::semantic()\n");
+    /* is(targ id tok tspec)
+     * is(targ id == tok2)
+     */
+
+    //printf("IsExp::semantic(%s)\n", toChars());
     if (id && !(sc->flags & SCOPEstaticif))
 	error("can only declare type aliases within static if conditionals");
 
@@ -4267,6 +4366,19 @@
 		    goto Lno;
 		tded = targ;
 		break;
+#if DMDV2
+	    case TOKconst:
+		if (!targ->isConst())
+		    goto Lno;
+		tded = targ;
+		break;
+
+	    case TOKinvariant:
+		if (!targ->isInvariant())
+		    goto Lno;
+		tded = targ;
+		break;
+#endif
 
 	    case TOKsuper:
 		// If class or interface, get the base class and interfaces
@@ -4293,11 +4405,12 @@
 	    case TOKdelegate:
 		if (targ->ty != Tdelegate)
 		    goto Lno;
-		tded = targ->next;	// the underlying function type
+		tded = ((TypeDelegate *)targ)->next;	// the underlying function type
 		break;
 
 	    case TOKfunction:
-	    {	if (targ->ty != Tfunction)
+	    {
+		if (targ->ty != Tfunction)
 		    goto Lno;
 		tded = targ;
 
@@ -4321,7 +4434,7 @@
 		 * delegate, or pointer to function.
 		 */
 		if (targ->ty == Tfunction)
-		    tded = targ->next;
+		    tded = ((TypeFunction *)targ)->next;
 		else if (targ->ty == Tdelegate)
 		    tded = targ->next->next;
 		else if (targ->ty == Tpointer && targ->next->ty == Tfunction)
@@ -4537,6 +4650,13 @@
 	if (e)
 	    return e;
 
+	if (e1->op == TOKslice)
+	{   // T[] op= ...
+	    typeCombine(sc);
+	    type = e1->type;
+	    return arrayOp(sc);
+	}
+
 	e1 = e1->modifiableLvalue(sc, e1);
 	e1->checkScalar();
 	type = e1->type;
@@ -4568,6 +4688,13 @@
 	if (e)
 	    return e;
 
+	if (e1->op == TOKslice)
+	{   // T[] op= ...
+	    typeCombine(sc);
+	    type = e1->type;
+	    return arrayOp(sc);
+	}
+
 	e1 = e1->modifiableLvalue(sc, e1);
 	e1->checkScalar();
 	type = e1->type;
@@ -4888,6 +5015,24 @@
 	eleft = NULL;
 	eright = e1;
     }
+#if DMDV2
+    if (e1->op == TOKtuple && ident == Id::offsetof)
+    {	/* 'distribute' the .offsetof to each of the tuple elements.
+	 */
+	TupleExp *te = (TupleExp *)e1;
+	Expressions *exps = new Expressions();
+	exps->setDim(te->exps->dim);
+	for (int i = 0; i < exps->dim; i++)
+	{   Expression *e = (Expression *)te->exps->data[i];
+	    e = e->semantic(sc);
+	    e = new DotIdExp(e->loc, e, Id::offsetof);
+	    exps->data[i] = (void *)e;
+	}
+	e = new TupleExp(loc, exps);
+	e = e->semantic(sc);
+	return e;
+    }
+#endif
 
     if (e1->op == TOKtuple && ident == Id::length)
     {
@@ -5048,7 +5193,7 @@
 	     ident != Id::mangleof && ident != Id::stringof)
     {
 	e = new PtrExp(loc, e1);
-	e->type = e1->type->next;
+	e->type = ((TypePointer *)e1->type)->next;
 	return e->type->dotExp(sc, e, ident);
     }
     else
@@ -5176,7 +5321,11 @@
 
 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
 {
-    //printf("DotVarExp::modifiableLvalue(%s)\n", toChars());
+#if 0
+    printf("DotVarExp::modifiableLvalue(%s)\n", toChars());
+    printf("e1->type = %s\n", e1->type->toChars());
+    printf("var->type = %s\n", var->type->toChars());
+#endif
 
     if (var->isCtorinit())
     {	// It's only modifiable if inside the right constructor
@@ -5265,6 +5414,12 @@
     if (t1)
 	t1 = t1->toBasetype();
     //t1->print();
+
+    /* Extract the following from e1:
+     *	s: the symbol which ti should be a member of
+     *	eleft: if not NULL, it is the 'this' pointer for ti
+     */
+
     if (e1->op == TOKdotexp)
     {	DotExp *de = (DotExp *)e1;
 	eleft = de->e1;
@@ -5295,7 +5450,7 @@
     }
     else if (t1 && t1->ty == Tpointer)
     {
-	t1 = t1->next->toBasetype();
+	t1 = ((TypePointer *)t1)->next->toBasetype();
 	if (t1->ty != Tstruct)
 	    goto L1;
 	s = t1->toDsymbol(sc);
@@ -5471,6 +5626,7 @@
     int i;
     Type *t1;
     int istemp;
+    Objects *targsi = NULL;	// initial list of template arguments
 
 #if LOGSEMANTIC
     printf("CallExp::semantic() %s\n", toChars());
@@ -5534,8 +5690,66 @@
 	}
     }
 
+#if DMDV2
+    /* This recognizes:
+     *	foo!(tiargs)(funcargs)
+     */
+    if (e1->op == TOKimport && !e1->type)
+    {	ScopeExp *se = (ScopeExp *)e1;
+	TemplateInstance *ti = se->sds->isTemplateInstance();
+	if (ti && !ti->semanticdone)
+	{
+	    /* Attempt to instantiate ti. If that works, go with it.
+	     * If not, go with partial explicit specialization.
+	     */
+	    ti->semanticTiargs(sc);
+	    unsigned errors = global.errors;
+	    global.gag++;
+	    ti->semantic(sc);
+	    global.gag--;
+	    if (errors != global.errors)
+	    {
+		/* Didn't work, go with partial explicit specialization
+		 */
+		global.errors = errors;
+		targsi = ti->tiargs;
+		e1 = new IdentifierExp(loc, ti->name);
+	    }
+	}
+    }
+
+    /* This recognizes:
+     *	expr.foo!(tiargs)(funcargs)
+     */
+    if (e1->op == TOKdotti && !e1->type)
+    {	DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1;
+	TemplateInstance *ti = se->ti;
+	if (!ti->semanticdone)
+	{
+	    /* Attempt to instantiate ti. If that works, go with it.
+	     * If not, go with partial explicit specialization.
+	     */
+	    ti->semanticTiargs(sc);
+	    Expression *etmp;
+	    unsigned errors = global.errors;
+	    global.gag++;
+	    etmp = e1->semantic(sc);
+	    global.gag--;
+	    if (errors != global.errors)
+	    {
+		global.errors = errors;
+		targsi = ti->tiargs;
+		e1 = new DotIdExp(loc, se->e1, ti->name);
+	    }
+	    else
+		e1 = etmp;
+	}
+    }
+#endif
+
     istemp = 0;
 Lagain:
+    //printf("Lagain: %s\n", toChars());
     f = NULL;
     if (e1->op == TOKthis || e1->op == TOKsuper)
     {
@@ -5804,16 +6018,16 @@
     else if (t1->ty != Tfunction)
     {
 	if (t1->ty == Tdelegate)
-	{
-	    assert(t1->next->ty == Tfunction);
-	    tf = (TypeFunction *)(t1->next);
+	{   TypeDelegate *td = (TypeDelegate *)t1;
+	    assert(td->next->ty == Tfunction);
+	    tf = (TypeFunction *)(td->next);
 	    goto Lcheckargs;
 	}
-	else if (t1->ty == Tpointer && t1->next->ty == Tfunction)
+	else if (t1->ty == Tpointer && ((TypePointer *)t1)->next->ty == Tfunction)
 	{   Expression *e;
 
 	    e = new PtrExp(loc, e1);
-	    t1 = t1->next;
+	    t1 = ((TypePointer *)t1)->next;
 	    e->type = t1;
 	    e1 = e;
 	}
@@ -5909,10 +6123,11 @@
     {
 	Type *t = type;
 	int offset = 0;
-
-	if (f->tintro->next->isBaseOf(t, &offset) && offset)
-	{
-	    type = f->tintro->next;
+	TypeFunction *tf = (TypeFunction *)f->tintro;
+
+	if (tf->next->isBaseOf(t, &offset) && offset)
+	{
+	    type = tf->next;
 	    return castTo(sc, t);
 	}
     }
@@ -5974,9 +6189,7 @@
 	    FuncDeclaration *f = dve->var->isFuncDeclaration();
 
 	    if (f)
-	    {	Expression *e;
-
-		e = new DelegateExp(loc, dve->e1, f);
+	    {	Expression *e = new DelegateExp(loc, dve->e1, f);
 		e = e->semantic(sc);
 		return e;
 	    }
@@ -6018,7 +6231,7 @@
 	: UnaExp(loc, TOKstar, sizeof(PtrExp), e)
 {
     if (e->type)
-	type = e->type->next;
+	type = ((TypePointer *)e->type)->next;
 }
 
 PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
@@ -6108,7 +6321,8 @@
 	    return e;
 
 	e1->checkNoBool();
-	e1->checkArithmetic();
+	if (e1->op != TOKslice)
+	    e1->checkArithmetic();
 	type = e1->type;
     }
     return this;
@@ -6157,7 +6371,8 @@
 	    return e;
 
 	e1->checkNoBool();
-	e1 = e1->checkIntegral();
+	if (e1->op != TOKslice)
+	    e1 = e1->checkIntegral();
 	type = e1->type;
     }
     return this;
@@ -6238,7 +6453,7 @@
 	    break;
 	}
 	case Tpointer:
-	    tb = tb->next->toBasetype();
+	    tb = ((TypePointer *)tb)->next->toBasetype();
 	    if (tb->ty == Tstruct)
 	    {
 		TypeStruct *ts = (TypeStruct *)tb;
@@ -6569,7 +6784,7 @@
 	return e;
     }
 
-    type = t->next->arrayOf();
+    type = t->nextOf()->arrayOf();
     return e;
 
 Lerror:
@@ -6878,7 +7093,7 @@
 			    index, length);
 	    }
 #endif
-	    e->type = t1->next;
+	    e->type = t1->nextOf();
 	    break;
 	}
 
@@ -7199,6 +7414,20 @@
     {
 	e2 = e2->implicitCastTo(sc, e1->type);
     }
+
+    /* Look for array operations
+     */
+    if (e1->op == TOKslice && !ismemset &&
+	(e2->op == TOKadd || e2->op == TOKmin ||
+	 e2->op == TOKmul || e2->op == TOKdiv ||
+	 e2->op == TOKmod || e2->op == TOKxor ||
+	 e2->op == TOKand || e2->op == TOKor  ||
+	 e2->op == TOKtilde || e2->op == TOKneg))
+    {
+	type = e1->type;
+	return arrayOp(sc);
+    }
+
     type = e1->type;
     assert(type);
     return this;
@@ -7234,14 +7463,23 @@
     if (e)
 	return e;
 
-    e1 = e1->modifiableLvalue(sc, e1);
-
     Type *tb1 = e1->type->toBasetype();
     Type *tb2 = e2->type->toBasetype();
 
+    if (e1->op == TOKslice)
+    {
+	typeCombine(sc);
+	type = e1->type;
+	return arrayOp(sc);
+    }
+    else
+    {
+	e1 = e1->modifiableLvalue(sc, e1);
+    }
+
     if ((tb1->ty == Tarray || tb1->ty == Tsarray) &&
 	(tb2->ty == Tarray || tb2->ty == Tsarray) &&
-	tb1->next->equals(tb2->next)
+	tb1->nextOf()->equals(tb2->nextOf())
        )
     {
 	type = e1->type;
@@ -7263,11 +7501,7 @@
 		Expression *ea;
 		Expression *ex;
 
-		char name[6+6+1];
-		Identifier *id;
-		static int idn;
-		sprintf(name, "__name%d", ++idn);
-		id = Lexer::idPool(name);
+		Identifier *id = Lexer::uniqueId("__name");
 
 		v = new VarDeclaration(loc, tb1->pointerTo(), id, NULL);
 		v->semantic(sc);
@@ -7334,6 +7568,13 @@
     if (e)
 	return e;
 
+    if (e1->op == TOKslice)
+    {	// T[] -= ...
+	typeCombine(sc);
+	type = e1->type;
+	return arrayOp(sc);
+    }
+
     e1 = e1->modifiableLvalue(sc, e1);
     e1->checkScalar();
     e1->checkNoBool();
@@ -7397,10 +7638,10 @@
 	e = this;
     }
     else if ((tb1->ty == Tarray) &&
-	e2->implicitConvTo(tb1->next)
+	e2->implicitConvTo(tb1->nextOf())
        )
     {	// Append element
-	e2 = e2->castTo(sc, tb1->next);
+	e2 = e2->castTo(sc, tb1->nextOf());
 	type = e1->type;
 	e = this;
     }
@@ -7430,6 +7671,13 @@
     if (e)
 	return e;
 
+    if (e1->op == TOKslice)
+    {	// T[] -= ...
+	typeCombine(sc);
+	type = e1->type;
+	return arrayOp(sc);
+    }
+
     e1 = e1->modifiableLvalue(sc, e1);
     e1->checkScalar();
     e1->checkNoBool();
@@ -7486,6 +7734,13 @@
     if (e)
 	return e;
 
+    if (e1->op == TOKslice)
+    {	// T[] -= ...
+	typeCombine(sc);
+	type = e1->type;
+	return arrayOp(sc);
+    }
+
     e1 = e1->modifiableLvalue(sc, e1);
     e1->checkScalar();
     e1->checkNoBool();
@@ -7690,7 +7945,7 @@
 
         if ((tb1->ty == Tarray || tb1->ty == Tsarray) &&
             (tb2->ty == Tarray || tb2->ty == Tsarray) &&
-            tb1->next->equals(tb2->next)
+            tb1->nextOf()->equals(tb2->nextOf())
            )
         {
             type = e1->type;
@@ -7776,17 +8031,22 @@
 
 	    typeCombine(sc);		// make sure pointer types are compatible
 	    type = Type::tptrdiff_t;
-	    stride = t2->next->size();
-        if (!stride)
-            return new IntegerExp(0, 0, Type::tptrdiff_t);
-	    e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t));
-	    e->type = Type::tptrdiff_t;
+	    stride = t2->nextOf()->size();
+	    if (stride == 0)
+	    {
+		e = new IntegerExp(loc, 0, Type::tptrdiff_t);
+	    }
+	    else
+	    {
+		e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t));
+		e->type = Type::tptrdiff_t;
+	    }
 	    return e;
 	}
 	else if (t2->isintegral())
 	    e = scaleFactor(sc);
 	else
-	{   error("incompatible types for -");
+	{   error("incompatible types for minus");
 	    return new IntegerExp(0);
 	}
     }
@@ -7864,7 +8124,7 @@
 	if ((tb1->ty == Tsarray || tb1->ty == Tarray) &&
 	    e2->type->equals(tb1->next))
 	{
-	    type = tb1->next->arrayOf();
+	    type = tb1->nextOf()->arrayOf();
 	    if (tb2->ty == Tarray)
 	    {	// Make e2 into [e2]
 		e2 = new ArrayLiteralExp(e2->loc, e2);
@@ -7875,7 +8135,7 @@
 	else if ((tb2->ty == Tsarray || tb2->ty == Tarray) &&
 	    e1->type->equals(tb2->next))
 	{
-	    type = tb2->next->arrayOf();
+	    type = tb2->nextOf()->arrayOf();
 	    if (tb1->ty == Tarray)
 	    {	// Make e1 into [e1]
 		e1 = new ArrayLiteralExp(e1->loc, e1);
@@ -7904,6 +8164,7 @@
 	}
 	else
 	{
+	    //printf("(%s) ~ (%s)\n", e1->toChars(), e2->toChars());
 	    error("Can only concatenate arrays, not (%s ~ %s)",
 		e1->type->toChars(), e2->type->toChars());
 	    type = Type::tint32;
@@ -7939,8 +8200,10 @@
 	return e;
 
     typeCombine(sc);
-    e1->checkArithmetic();
-    e2->checkArithmetic();
+    if (e1->op != TOKslice && e2->op != TOKslice)
+    {	e1->checkArithmetic();
+	e2->checkArithmetic();
+    }
     if (type->isfloating())
     {	Type *t1 = e1->type;
 	Type *t2 = e2->type;
@@ -8003,8 +8266,10 @@
 	return e;
 
     typeCombine(sc);
-    e1->checkArithmetic();
-    e2->checkArithmetic();
+    if (e1->op != TOKslice && e2->op != TOKslice)
+    {	e1->checkArithmetic();
+	e2->checkArithmetic();
+    }
     if (type->isfloating())
     {	Type *t1 = e1->type;
 	Type *t2 = e2->type;
@@ -8068,8 +8333,10 @@
 	return e;
 
     typeCombine(sc);
-    e1->checkArithmetic();
-    e2->checkArithmetic();
+    if (e1->op != TOKslice && e2->op != TOKslice)
+    {	e1->checkArithmetic();
+	e2->checkArithmetic();
+    }
     if (type->isfloating())
     {	type = e1->type;
 	if (e2->type->iscomplex())
@@ -8180,8 +8447,10 @@
 	else
 	{
 	    typeCombine(sc);
-	    e1->checkIntegral();
-	    e2->checkIntegral();
+	    if (e1->op != TOKslice && e2->op != TOKslice)
+	    {   e1->checkIntegral();
+		e2->checkIntegral();
+	    }
 	}
     }
     return this;
@@ -8211,8 +8480,10 @@
 	else
 	{
 	    typeCombine(sc);
-	    e1->checkIntegral();
-	    e2->checkIntegral();
+	    if (e1->op != TOKslice && e2->op != TOKslice)
+	    {   e1->checkIntegral();
+		e2->checkIntegral();
+	    }
 	}
     }
     return this;
@@ -8242,8 +8513,10 @@
 	else
 	{
 	    typeCombine(sc);
-	    e1->checkIntegral();
-	    e2->checkIntegral();
+	    if (e1->op != TOKslice && e2->op != TOKslice)
+	    {   e1->checkIntegral();
+		e2->checkIntegral();
+	    }
 	}
     }
     return this;
@@ -8414,7 +8687,7 @@
 	e1 = e1->implicitCastTo(sc, ta->index);
 
 	// Return type is pointer to value
-	type = ta->next->pointerTo();
+	type = ta->nextOf()->pointerTo();
     }
     return this;
 }
@@ -8501,6 +8774,7 @@
 #endif
     else
 	e = this;
+    //printf("CmpExp: %s\n", e->toChars());
     return e;
 }