Permalink
Browse files

Merge pull request #571 from 9rnsr/fix6940

Issue 6939 & 6940 & 7136 - Fix type combination
  • Loading branch information...
WalterBright committed Dec 20, 2011
2 parents 3b0e7d0 + 5ebdd82 commit 06fe1ce97ef56cb86821114024c55f8d5fe0073c
Showing with 132 additions and 24 deletions.
  1. +61 −24 src/cast.c
  2. +27 −0 test/runnable/aliasthis.d
  3. +44 −0 test/runnable/testconst.d
View
@@ -1671,13 +1671,16 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
t = t2;
else if (t2n->ty == Tvoid)
;
else if (t1->implicitConvTo(t2))
{
goto Lt2;
}
else if (t2->implicitConvTo(t1))
{
goto Lt1;
}
else if (t1n->ty == Tfunction && t2n->ty == Tfunction)
{
if (t1->implicitConvTo(t2))
goto Lt2;
if (t2->implicitConvTo(t1))
goto Lt1;
TypeFunction *tf1 = (TypeFunction *)t1n;
TypeFunction *tf2 = (TypeFunction *)t2n;
TypeFunction *d = (TypeFunction *)tf1->syntaxCopy();
@@ -1715,8 +1718,11 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
}
else if (t1n->mod != t2n->mod)
{
t1 = t1n->mutableOf()->constOf()->pointerTo();
t2 = t2n->mutableOf()->constOf()->pointerTo();
if (!t1n->isImmutable() && !t2n->isImmutable() && t1n->isShared() != t2n->isShared())
goto Lincompatible;
unsigned char mod = MODmerge(t1n->mod, t2n->mod);
t1 = t1n->castMod(mod)->pointerTo();
t2 = t2n->castMod(mod)->pointerTo();
t = t1;
goto Lagain;
}
@@ -1740,7 +1746,19 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
goto Lincompatible;
}
else
{
t1 = t1n->constOf()->pointerTo();
t2 = t2n->constOf()->pointerTo();
if (t1->implicitConvTo(t2))
{
goto Lt2;
}
else if (t2->implicitConvTo(t1))
{
goto Lt1;
}
goto Lincompatible;
}
}
else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
(e2->op == TOKnull && t2->ty == Tpointer && t2->nextOf()->ty == Tvoid ||
@@ -1786,30 +1804,54 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
(t2->ty == Tsarray || t2->ty == Tarray || t2->ty == Tpointer) &&
t1->nextOf()->mod != t2->nextOf()->mod
)
{ unsigned char mod = MODmerge(t1->nextOf()->mod, t2->nextOf()->mod);
{
Type *t1n = t1->nextOf();
Type *t2n = t2->nextOf();
unsigned char mod;
if (e1->op == TOKnull && e2->op != TOKnull)
mod = t2n->mod;
else if (e1->op != TOKnull && e2->op == TOKnull)
mod = t1n->mod;
else if (!t1n->isImmutable() && !t2n->isImmutable() && t1n->isShared() != t2n->isShared())
goto Lincompatible;
else
mod = MODmerge(t1n->mod, t2n->mod);
if (t1->ty == Tpointer)
t1 = t1->nextOf()->castMod(mod)->pointerTo();
t1 = t1n->castMod(mod)->pointerTo();
else
t1 = t1->nextOf()->castMod(mod)->arrayOf();
t1 = t1n->castMod(mod)->arrayOf();
if (t2->ty == Tpointer)
t2 = t2->nextOf()->castMod(mod)->pointerTo();
t2 = t2n->castMod(mod)->pointerTo();
else
t2 = t2->nextOf()->castMod(mod)->arrayOf();
t2 = t2n->castMod(mod)->arrayOf();
t = t1;
goto Lagain;
}
else if (t1->ty == Tclass || t2->ty == Tclass)
else if (t1->ty == Tclass && t2->ty == Tclass)
{
if (t1->mod != t2->mod)
{ unsigned char mod = MODmerge(t1->mod, t2->mod);
{
unsigned char mod;
if (e1->op == TOKnull && e2->op != TOKnull)
mod = t2->mod;
else if (e1->op != TOKnull && e2->op == TOKnull)
mod = t1->mod;
else if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
goto Lincompatible;
else
mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
t2 = t2->castMod(mod);
t = t1;
goto Lagain;
}
goto Lcc;
}
else if (t1->ty == Tclass || t2->ty == Tclass)
{
Lcc:
while (1)
{
int i1 = e2->implicitConvTo(t1);
@@ -1876,6 +1918,8 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
{
if (t1->mod != t2->mod)
{
if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
goto Lincompatible;
unsigned char mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
t2 = t2->castMod(mod);
@@ -1931,15 +1975,6 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
}
else if (t1->ty == Tstruct || t2->ty == Tstruct)
{
if (t1->mod != t2->mod)
{
unsigned char mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
t2 = t2->castMod(mod);
t = t1;
goto Lagain;
}
if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis)
{
e1 = new DotIdExp(e1->loc, e1, ((TypeStruct *)t1)->sym->aliasthis->ident);
@@ -1987,6 +2022,8 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
else if (t1->isintegral() && t2->isintegral())
{
assert(t1->ty == t2->ty);
if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
goto Lincompatible;
unsigned char mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
View
@@ -691,6 +691,32 @@ void test6929()
static assert(!is(typeof(1? t:s)));
}
/***************************************************/
// 7136
void test7136()
{
struct X
{
Object get() immutable { return null; }
alias get this;
}
immutable(X) x;
Object y;
static assert( is(typeof(1?x:y) == Object)); // fails
static assert(!is(typeof(1?x:y) == const(Object))); // fails
struct A
{
int[] get() immutable { return null; }
alias get this;
}
immutable(A) a;
int[] b;
static assert( is(typeof(1?a:b) == int[])); // fails
static assert(!is(typeof(1?a:b) == const(int[]))); // fails
}
/***************************************************/
int main()
@@ -719,6 +745,7 @@ int main()
test6832();
test6928();
test6929();
test7136();
printf("Success\n");
return 0;
View
@@ -2165,6 +2165,48 @@ static assert((shared(inout(const(int)[]))).stringof == "shared(inout(const(int)
static assert((shared(inout(const(int)[])[])).stringof == "shared(inout(const(int)[])[])");
static assert((shared(inout(const(immutable(int)[])[])[])).stringof == "shared(inout(const(immutable(int)[])[])[])");
/************************************/
// 6939
void test6939()
{
shared int* x;
immutable int* y;
const int* z;
static assert( is(typeof(1?x:y) == shared(const(int))*)); // fail
static assert(!is(typeof(1?x:y) == const(int)*)); // fail
static assert(!is(typeof(1?x:z))); // fail
shared int[] a;
immutable int[] b;
const int[] c;
static assert( is(typeof(1?a:b) == shared(const(int))[])); // pass (ok)
static assert(!is(typeof(1?a:b) == const(int)[])); // pass (ok)
static assert(!is(typeof(1?a:c))); // fail
}
/************************************/
// 6940
void test6940()
{
immutable(int*)* x;
int** y;
static assert(is(typeof(x) : const(int*)*)); // ok
static assert(is(typeof(y) : const(int*)*)); // ok
static assert(is(typeof(1?x:y) == const(int*)*));
immutable(int[])[] a;
int[][] b;
static assert(is(typeof(a) : const(int[])[])); // ok
static assert(is(typeof(b) : const(int[])[])); // ok
static assert(is(typeof(1?a:b) == const(int[])[]));
immutable(int)** v;
int** w;
static assert(is(typeof(1?v:w) == const(int*)*));
}
/************************************/
int main()
@@ -2264,6 +2306,8 @@ int main()
test6866();
test6870();
test6912();
test6939();
test6940();
printf("Success\n");
return 0;

0 comments on commit 06fe1ce

Please sign in to comment.