diff --git a/src/expression.c b/src/expression.c index c2515938fc9a..95169c22de74 100644 --- a/src/expression.c +++ b/src/expression.c @@ -13571,6 +13571,18 @@ Expression *EqualExp::semantic(Scope *sc) return e; } + if (t1->ty == Tpointer || t2->ty == Tpointer) + { + /* Rewrite: + * ptr1 == ptr2 + * as: + * ptr1 is ptr2 + */ + e = new IdentityExp(op == TOKequal ? TOKidentity : TOKnotidentity, loc, e1, e2); + e = e->semantic(sc); + return e; + } + if (t1->ty == Tstruct && t2->ty == Tstruct) { StructDeclaration *sd = ((TypeStruct *)t1)->sym; diff --git a/src/optimize.c b/src/optimize.c index e02f9608aa75..06ca9fc63a1d 100644 --- a/src/optimize.c +++ b/src/optimize.c @@ -74,7 +74,18 @@ Expression *expandVar(int result, VarDeclaration *v) { AssignExp *ae = (AssignExp *)ei; ei = ae->e2; - if (ei->isConst() != 1 && ei->op != TOKstring) + if (ei->isConst() == 1) + { + } + else if (ei->op == TOKstring) + { + // Bugzilla 14459: We should not constfold the string literal + // if it's typed as a C string, because the value expansion + // will drop the pointer identity. + if (!(result & WANTexpand) && ei->type->toBasetype()->ty == Tpointer) + goto L1; + } + else goto L1; if (ei->type == v->type) diff --git a/test/runnable/constfold.d b/test/runnable/constfold.d index 383d838be2d1..e0dd372ed9ce 100644 --- a/test/runnable/constfold.d +++ b/test/runnable/constfold.d @@ -743,6 +743,37 @@ void test3697or() auto z = y || 1 / x; } +/************************************/ +// 14459 + +void test14459() +{ + const char* s0 = "hi0"; + const(char)* p0 = s0; + assert(p0 == s0); + + const char* s1 = "hi1"; + const char* s2 = "hi2"; + const char* s3 = "hi3"; + const char* s4 = "hi4"; + const char* s5 = "hi5"; + const char* s6 = "hi6"; + const char* s7 = "hi7"; + const char* s8 = "hi8"; + const char* s9 = "hi9"; + const char* s10 = "hi10"; + const char* s11 = "hi11"; + const char* s12 = "hi12"; + const char* s13 = "hi13"; + const char* s14 = "hi14"; + const char* s15 = "hi15"; + assert(p0 == s0); // ok + const char* s16 = "hi16"; + assert(p0 == s0); // ok <- fails +} + +/************************************/ + int main() { test1(); @@ -757,6 +788,7 @@ int main() test11159(); test13977(); test13978(); + test14459(); printf("Success\n"); return 0;