Skip to content

Commit

Permalink
fix Issue 13907 - Surrogate pairs in wchar string literal will cause …
Browse files Browse the repository at this point in the history
…incorrect length match

Stop considering lengthen conversion in StringExp::implicitConvTo().
  • Loading branch information
9rnsr committed Dec 29, 2014
1 parent f606bd4 commit 6d73218
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 11 deletions.
19 changes: 12 additions & 7 deletions src/cast.c
Expand Up @@ -577,15 +577,19 @@ MATCH implicitConvTo(Expression *e, Type *t)
case Tsarray:
if (e->type->ty == Tsarray)
{
if (((TypeSArray *)e->type)->dim->toInteger() !=
((TypeSArray *)t)->dim->toInteger())
return;
TY tynto = t->nextOf()->ty;
if (tynto == tyn)
{
result = MATCHexact;
if (((TypeSArray *)e->type)->dim->toInteger() ==
((TypeSArray *)t)->dim->toInteger())
{
result = MATCHexact;
}
return;
}
int szto = t->nextOf()->size();
if (e->length(szto) != ((TypeSArray *)t)->dim->toInteger())
return;
if (!e->committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))
{
result = MATCHexact;
Expand All @@ -594,10 +598,10 @@ MATCH implicitConvTo(Expression *e, Type *t)
}
else if (e->type->ty == Tarray)
{
if (e->length() >
((TypeSArray *)t)->dim->toInteger())
return;
TY tynto = t->nextOf()->ty;
int sznto = t->nextOf()->size();
if (e->length(sznto) != ((TypeSArray *)t)->dim->toInteger())
return;
if (tynto == tyn)
{
result = MATCHexact;
Expand All @@ -609,6 +613,7 @@ MATCH implicitConvTo(Expression *e, Type *t)
return;
}
}
/* fall through */
case Tarray:
case Tpointer:
Type *tn = t->nextOf();
Expand Down
43 changes: 39 additions & 4 deletions test/runnable/literal.d
@@ -1,8 +1,5 @@
// REQUIRED_ARGS: -d
// PERMUTE_ARGS: -dw

import std.stdio;
import core.stdc.stdlib;
extern(C) int printf(const char*, ...);

enum
{
Expand Down Expand Up @@ -167,10 +164,48 @@ void test2()
assert(e == 2_463_534_242UL);
}

/***************************************************/
// 13907

void f13907_1(wchar[1] a) {}
void f13907_2(wchar[2] a) {}
void f13907_3(wchar[3] a) {}

auto f13907_12(char[1]) { return 1; }
auto f13907_12(char[2]) { return 2; }

void test13907()
{
static assert(!__traits(compiles, { f13907_1("\U00010000"w); }));
static assert(!__traits(compiles, { f13907_1("\U00010000" ); }));
f13907_2("\U00010000"w);
f13907_2("\U00010000");
static assert(!__traits(compiles, { f13907_3("\U00010000"w); }));
static assert(!__traits(compiles, { f13907_3("\U00010000" ); }));

assert(f13907_12("a") == 1);

// regression tests for the lengthen behavior in initializer
enum const(char*) p = "hello world";
static assert(!__traits(compiles, { static char[5] a = "hello world"; })); // truncation is not allowed
static assert(!__traits(compiles, { static void[20] a = "hello world"; }));
static assert(!__traits(compiles, { static int[20] a = "hello world"; }));
static assert(!__traits(compiles, { static char[20] a = "hello world"w; }));
static assert(!__traits(compiles, { static wchar[20] a = "hello world"d; }));
static assert(!__traits(compiles, { static dchar[20] a = "hello world"c; }));
static assert(!__traits(compiles, { static char[20] a = p; }));
static char[20] csa = "hello world"; // extending is allowed
static wchar[20] wsa = "hello world"; // ok
static dchar[20] dsa = "hello world"; // ok
}

/***************************************************/

int main()
{
test1();
test2();
test13907();

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

0 comments on commit 6d73218

Please sign in to comment.