From 6b848c352f0865986fc6a0ed9e09effc4f014458 Mon Sep 17 00:00:00 2001 From: k-hara Date: Wed, 30 Sep 2015 13:40:47 +0900 Subject: [PATCH] fix Issue 7979 - Alias this does not work with switch --- src/statement.d | 48 ++++++++++++++++++++++++++++----------- test/runnable/aliasthis.d | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/src/statement.d b/src/statement.d index 67b538a7345a..905c1d896fa3 100644 --- a/src/statement.d +++ b/src/statement.d @@ -11,6 +11,7 @@ module ddmd.statement; import core.stdc.stdarg; import core.stdc.stdio; import ddmd.aggregate; +import ddmd.aliasthis; import ddmd.arrayop; import ddmd.arraytypes; import ddmd.attrib; @@ -3614,29 +3615,50 @@ public: tf = sc.tf; if (cases) return this; // already run + bool conditionError = false; condition = condition.semantic(sc); condition = resolveProperties(sc, condition); + + Type att = null; TypeEnum te = null; - // preserve enum type for final switches - if (condition.type.ty == Tenum) - te = cast(TypeEnum)condition.type; - if (condition.type.isString()) + while (condition.op != TOKerror) { - // If it's not an array, cast it to one - if (condition.type.ty != Tarray) + // preserve enum type for final switches + if (condition.type.ty == Tenum) + te = cast(TypeEnum)condition.type; + if (condition.type.isString()) { - condition = condition.implicitCastTo(sc, condition.type.nextOf().arrayOf()); + // If it's not an array, cast it to one + if (condition.type.ty != Tarray) + { + condition = condition.implicitCastTo(sc, condition.type.nextOf().arrayOf()); + } + condition.type = condition.type.constOf(); + break; } - condition.type = condition.type.constOf(); - } - else - { condition = integralPromotions(condition, sc); - if (condition.op != TOKerror && !condition.type.isintegral()) + if (condition.op != TOKerror && condition.type.isintegral()) + break; + + auto ad = isAggregate(condition.type); + if (ad && ad.aliasthis && condition.type != att) + { + if (!att && condition.type.checkAliasThisRec()) + att = condition.type; + if (auto e = resolveAliasThis(sc, condition, true)) + { + condition = e; + continue; + } + } + + if (condition.op != TOKerror) { - error("'%s' must be of integral or string type, it is a %s", condition.toChars(), condition.type.toChars()); + error("'%s' must be of integral or string type, it is a %s", + condition.toChars(), condition.type.toChars()); conditionError = true; + break; } } condition = condition.optimize(WANTvalue); diff --git a/test/runnable/aliasthis.d b/test/runnable/aliasthis.d index 261c0992f4ff..47cc3f738e04 100644 --- a/test/runnable/aliasthis.d +++ b/test/runnable/aliasthis.d @@ -402,6 +402,11 @@ void test7() // Expression::checkToBoolean static assert(!__traits(compiles, { if (s1){} })); static assert(!__traits(compiles, { if (s3){} })); + + // SwitchStatement::semantic + static assert(!__traits(compiles, { switch (c0) { default: } })); + static assert(!__traits(compiles, { switch (c1) { default: } })); + static assert(!__traits(compiles, { switch (c3) { default: } })); } /***************************************************/ @@ -1191,6 +1196,46 @@ void test7945() s.v.foo7945(); // 4.OK, ufcs } +/***************************************************/ +// 7979 + +void test7979() +{ + static struct N + { + int val; + alias val this; + } + N n = N(1); + + switch (n) + { + case 0: + assert(0); + case 1: + break; + default: + assert(0); + } + + static struct S + { + string val; + alias val this; + } + S s = S("b"); + + switch (s) + { + case "a": + assert(0); + case "b": + break; + default: + assert(0); + } +} + /***************************************************/ // 7992 @@ -1902,6 +1947,7 @@ int main() test7731(); test7808(); test7945(); + test7979(); test7992(); test8169(); test8735();