Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 14459 - String literal merge bug causes incorrect runtime program behavior #4866

Merged
merged 2 commits into from Aug 6, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/expression.c
Expand Up @@ -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;
Expand Down
13 changes: 12 additions & 1 deletion src/optimize.c
Expand Up @@ -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)
Expand Down
32 changes: 32 additions & 0 deletions test/runnable/constfold.d
Expand Up @@ -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();
Expand All @@ -757,6 +788,7 @@ int main()
test11159();
test13977();
test13978();
test14459();

printf("Success\n");
return 0;
Expand Down