diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 78d5dd9543ca..42a036cb1570 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -13394,17 +13394,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.e1.op == EXP.variable) { - // Rewrite: e1 = e1 ^^ e2 + // Rewrite: e1 = cast(T)(e1 ^^ e2) e = new PowExp(exp.loc, exp.e1.syntaxCopy(), exp.e2); + e = new CastExp(exp.loc, e, exp.e1.type); e = new AssignExp(exp.loc, exp.e1, e); } else { - // Rewrite: ref tmp = e1; tmp = tmp ^^ e2 + // Rewrite: ref tmp = e1; tmp = cast(T)(tmp ^^ e2) auto v = copyToTemp(STC.ref_, "__powtmp", exp.e1); auto de = new DeclarationExp(exp.e1.loc, v); auto ve = new VarExp(exp.e1.loc, v); e = new PowExp(exp.loc, ve, exp.e2); + e = new CastExp(exp.loc, e, exp.e1.type); e = new AssignExp(exp.loc, new VarExp(exp.e1.loc, v), e); e = new CommaExp(exp.loc, de, e); } diff --git a/compiler/test/runnable/ctorpowtests.d b/compiler/test/runnable/ctorpowtests.d index f2cf5d8fe0cf..1df39babc812 100644 --- a/compiler/test/runnable/ctorpowtests.d +++ b/compiler/test/runnable/ctorpowtests.d @@ -266,9 +266,34 @@ int anotherPowTest() /************************************/ +// https://github.com/dlang/dmd/issues/19075 +// ^^= must compile for small integer types + +void test19075() +{ + byte bw = 10; + bw ^^= 3; + assert(bw == cast(byte) 1000); + + ubyte ubw = 10; + ubw ^^= 3; + assert(ubw == cast(ubyte) 1000); + + short sw = 100; + sw ^^= 3; + assert(sw == cast(short) 1_000_000); + + ushort usw = 100; + usw ^^= 3; + assert(usw == cast(ushort) 1_000_000); +} + +/************************************/ + void main() { assert(!__ctfe); assert(magicVariable()==2); test11159(); + test19075(); }