From 3252ddcf36f53928d04b62a601c0b7bb9d911cba Mon Sep 17 00:00:00 2001 From: k-hara Date: Fri, 7 Aug 2015 00:35:12 +0900 Subject: [PATCH 1/2] fix Issue 14459 - String literal merge bug causes incorrect runtime program behavior --- src/optimize.c | 13 ++++++++++++- test/runnable/constfold.d | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) 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; From f802a93845cb18c17ea9de7564b693bfae12692d Mon Sep 17 00:00:00 2001 From: k-hara Date: Fri, 7 Aug 2015 00:39:26 +0900 Subject: [PATCH 2/2] Reduce AST ambiguity in pointer comparison between `e1 == e2` and `e1 is e2` By this additional translation, we can have only one semantic analysis result for the equivalent expression forms. --- src/expression.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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;