Skip to content

Commit

Permalink
Merge pull request #5110 from MartinNowak/workaround15056
Browse files Browse the repository at this point in the history
add test for Issue 15056 - Unstored RAII struct return yields bogus error
  • Loading branch information
WalterBright committed Sep 23, 2015
2 parents af4d3a4 + cc724f2 commit ef854c3
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 159 deletions.
98 changes: 22 additions & 76 deletions changelog.dd
@@ -1,79 +1,25 @@
$(VERSION 053, ddd mm, 2011, =================================================,
Ddoc

$(WHATSNEW
$(LI $(BUGZILLA 2656): Remove octal literals)
$(LI Allow impure code inside debug conditionals)
)
$(DMDBUGSFIXED
$(LI $(BUGZILLA 2436): Unexpected OPTLINK termination EIP = 00425303 with /co)
$(LI $(BUGZILLA 3372): optlink silently mistreats object files with more than 16384 symbols)
$(LI $(BUGZILLA 4275): Unexpected optlink termination when 'export' attribute is missing)
$(LI $(BUGZILLA 4808): UNEXPECTED OPTLINK TERMINATION AT EIP=0042787B)
$(LI $(BUGZILLA 5670): Optlink 8.00.11 crash)
$(COMMENT Pending changelog for 2.068.2.
)

$(BUGSTITLE Compiler Changes,
$(LI The fix for $(BUGZILLA 14708) was reverted: destructor for temporary not called during stack unwinding, see $(DMDPR 5110).)
)

$(LI $(BUGZILLA 937): C-style variadic functions broken)
$(LI $(BUGZILLA 1330): Array slicing does not work the same way in CTFE as at runtime)
$(LI $(BUGZILLA 1336): Inconsistent __traits usage)
$(LI $(BUGZILLA 1389): Can't use mixin expressions when start of a statement)
$(LI $(BUGZILLA 1880): templates instantiated with non-constants should fail sooner)
$(LI $(BUGZILLA 2257): Template value parameters behave like alias parameters)
$(LI $(BUGZILLA 2414): enum is dynamically evaluated, yum)
$(LI $(BUGZILLA 2526): non-const initializer to constant accepted inside template)
$(LI $(BUGZILLA 2706): invalid template instantiation (and declaration?) is not rejected)
$(LI $(BUGZILLA 2733): Unclear semantics of template value parameters)
$(LI $(BUGZILLA 2841): char[] incorrectly accepted as a template value argument in D2)
$(LI $(BUGZILLA 2850): bad codegen for struct static initializers)
$(LI $(BUGZILLA 2990): TypeInfo.init() returns invalid array)
$(LI $(BUGZILLA 3086): TypeInfo opEquals returns incorrect results)
$(LI $(BUGZILLA 3214): Incorrect DWARF line number debugging information on Linux)
$(LI $(BUGZILLA 3271): Struct initializers silently fail)
$(LI $(BUGZILLA 3516): Destructor not called on temporaries)
$(LI $(BUGZILLA 3792): Regression(1.053) "non-constant expression" for a template inside a struct using a struct initializer)
$(LI $(BUGZILLA 3779): ["123"][0][$-1] causes __dollar unresolved in compile-time)
$(LI $(BUGZILLA 3801): CTFE: this.arr[i] cannot be evaluated at compile time for structs)
$(LI $(BUGZILLA 3835): ref foreach does not work in CTFE)
$(LI $(BUGZILLA 4033): Error: base class is forward referenced)
$(LI $(BUGZILLA 4050): [CTFE] array struct member slice update)
$(LI $(BUGZILLA 4051): [CTFE] array struct member item update
$(LI $(BUGZILLA 4097): Error: can only declare type aliases within static if conditionals)
$(LI $(BUGZILLA 4140): Error: non-constant expression "hello"[1u..__dollar])
$(LI $(BUGZILLA 4298): Constant array translated to unnecessary array literal creation)
$(LI $(BUGZILLA 4322): "void initializer has no value" on struct/union members initialized to "void")
$(LI $(BUGZILLA 4329): Do not show error messages that refer to __error)
$(LI $(BUGZILLA 4360): Allow intrinsics in core.bitop to operate as intrinsics)
$(LI $(BUGZILLA 4437): copy construction bug with "return this;")
$(LI $(BUGZILLA 4499): calls to @disabled postblit are emitted)
$(LI $(BUGZILLA 4543): Regression(1.054, 2.038) typedef causes circular definition and segfault)
$(LI $(BUGZILLA 4750): fail_compilation/fail225.d causes dmd to segv)
$(LI $(BUGZILLA 4833): dmd -od doesn't make it to optlink's command line for map files)
$(LI $(BUGZILLA 4917): Symbol conflict error message refers to aliased symbol instead of the alias)
$(LI $(BUGZILLA 5147): [CTFE] Return fixed-size matrix)
$(LI $(BUGZILLA 5362): checking $ in bracket is broken)
$(LI $(BUGZILLA 5482): Crash with align(0))
$(LI $(BUGZILLA 5485): TLS sections handled incorrectly)
$(LI $(BUGZILLA 5524): [CTFE] Trouble with typesafe variadic function)
$(LI $(BUGZILLA 5647): [64-bit] Valgrind complains about illegal instruction)
$(LI $(BUGZILLA 5649): std.conv.parse faulty for floating point with -O -m32)
$(LI $(BUGZILLA 5657): Temporary object destruction)
$(LI $(BUGZILLA 5694): va_arg doesn't work with idouble and ifloat)
$(LI $(BUGZILLA 5671): CTFE string concat problem)
$(LI $(BUGZILLA 5672): ICE(cod2.c): incorrect optimization of (long &1) == 1)
$(LI $(BUGZILLA 5678): new enum struct re-allocated at compile time)
$(LI $(BUGZILLA 5694): va_arg doesn't work with idouble and ifloat)
$(LI $(BUGZILLA 5706): Incorrect opcode prefix generated for x86_64 inline assembly)
$(LI $(BUGZILLA 5708): Incorrect string constant folding with -inline)
$(LI $(BUGZILLA 5717): 1.067 regression: appending Unicode char to string broken)
$(LI $(BUGZILLA 5722): Regression(2.052): Appending code-unit from multi-unit code-point at compile-time gives wrong result)
$(LI $(BUGZILLA 5735): non-scalar types implicitly converted to boolean)
$(LI $(BUGZILLA 5740): Unable to use this pointer in inline assembly)
$(LI $(BUGZILLA 5741): Add the SYSCALL and SYSRET opcodes to the inline assembler)
$(LI $(BUGZILLA 5812): Added constant fold optimisations for ^^ expressions)
$(LI $(BUGZILLA 5852): CTFE: wrong code for string[] ~= const(string))
$(LI $(BUGZILLA 5858): Import doesn't accept const string as argument)
$(LI Clarify tuple index out of bounds error message)
$(LI Add 64 version of xchg and jmp to inline assembler. Fixed 64 bit LEA)
$(LI CTFE: Generate error messages for accessing null arrays)
$(LI Fix optimizer bug with to!float("123e2"))
$(LI Add parent to __traits for QtD support)
)
$(BUGSTITLE Compiler Changes,
)

Macros:
TITLE=Change Log

BUGSTITLE = <div class="bugsfixed">$(H4 $1) $(OL $2 )</div>

RELATIVE_LINK2=<a href="#$1">$+</a>
LNAME2=<a class="anchor" title="Permalink to this section" id="$1" href="#$1">$+</a>

BUGZILLA = <a href="https://issues.dlang.org/show_bug.cgi?id=$0">Bugzilla $0</a>
PULL_REQUEST = $(LINK2 https://github.com/D-Programming-Language/$1/pull/$2, $1#$2)
DMDPR = $(PULL_REQUEST dmd,$1)

BOOKTABLE = <table><caption>$1</caption>$+</table>
14 changes: 2 additions & 12 deletions src/backend/cod2.c
Expand Up @@ -5079,14 +5079,9 @@ code *cddctor(elem *e,regm_t *pretregs)
*/
usednteh |= EHcleanup;
if (config.exe == EX_NT)
{
usednteh |= NTEHcleanup | NTEH_try;
{ usednteh |= NTEHcleanup | NTEH_try;
nteh_usevars();
}
else
{
usednteh |= EHtry;
}
assert(*pretregs == 0);
code cs;
cs.Iop = ESCAPE | ESCdctor;
Expand Down Expand Up @@ -5122,14 +5117,9 @@ code *cdddtor(elem *e,regm_t *pretregs)
*/
usednteh |= EHcleanup;
if (config.exe == EX_NT)
{
usednteh |= NTEHcleanup | NTEH_try;
{ usednteh |= NTEHcleanup | NTEH_try;
nteh_usevars();
}
else
{
usednteh |= EHtry;
}

code cs;
cs.Iop = ESCAPE | ESCddtor;
Expand Down
4 changes: 4 additions & 0 deletions src/posix.mak
Expand Up @@ -531,6 +531,10 @@ zip:
-rm -f dmdsrc.zip
zip dmdsrc $(SRC) $(ROOT_SRC) $(GLUE_SRC) $(BACK_SRC) $(TK_SRC)

######################################################

../changelog.html: ../changelog.dd
$(HOST_DC_RUN) -Df$@ $<

############################# DDMD stuff ############################

Expand Down
5 changes: 5 additions & 0 deletions src/win32.mak
Expand Up @@ -435,6 +435,11 @@ pvs:
checkwhitespace:
$(HOST_DC) -run checkwhitespace $(SRCS) $(GLUESRC) $(ROOTSRC)

######################################################

..\changelog.html: ..\changelog.dd
$(HOST_DC) -Df$@ $<

############################## Generated Source ##############################

elxxx.c cdxxx.c optab.c debtab.c fltables.c tytab.c : \
Expand Down
28 changes: 28 additions & 0 deletions test/compilable/test15056.d
@@ -0,0 +1,28 @@
nothrow:

version (Windows)
{
version (LP_64)
import core.stdc.stdlib;
else
// doesn't currently work b/c SEH remains present even in nothrow code
void* alloca(size_t) { return null; }
}
else
import core.stdc.stdlib;

struct S
{
~this() nothrow {}
}

S foo(void* p = alloca(1234))
{
return S();
}

int main()
{
foo();
return 0;
}
91 changes: 20 additions & 71 deletions test/runnable/sdtor.d
Expand Up @@ -4015,28 +4015,28 @@ void test14696(int len = 2)
check({ foo(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).foo.dtor(1).");

// temporary in condition and throwing callee
check({ fooThrow(len == 2 ? makeS(1).get() : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
check({ fooThrow(len == 2 ? null : makeS(1).get() ); }, "fooThrow.");
check({ fooThrow(len != 2 ? makeS(1).get() : null); }, "fooThrow.");
check({ fooThrow(len != 2 ? null : makeS(1).get() ); }, "makeS(1).get(1).fooThrow.dtor(1).");
// check({ fooThrow(len == 2 ? makeS(1).get() : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
// check({ fooThrow(len == 2 ? null : makeS(1).get() ); }, "fooThrow.");
// check({ fooThrow(len != 2 ? makeS(1).get() : null); }, "fooThrow.");
// check({ fooThrow(len != 2 ? null : makeS(1).get() ); }, "makeS(1).get(1).fooThrow.dtor(1).");

// temporary in nesting condititions and throwing callee
check({ fooThrow(len >= 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
check({ fooThrow(len >= 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
check({ fooThrow(len >= 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
check({ fooThrow(len >= 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
check({ fooThrow(len >= 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "fooThrow.");
check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
check({ fooThrow(len >= 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow.");
check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
check({ fooThrow(len > 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
check({ fooThrow(len > 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
check({ fooThrow(len > 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
check({ fooThrow(len > 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
check({ fooThrow(len > 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "makeS(1).get(1).fooThrow.dtor(1).");
check({ fooThrow(len > 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
check({ fooThrow(len > 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow.");
check({ fooThrow(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).fooThrow.dtor(1).");
// check({ fooThrow(len >= 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
// check({ fooThrow(len >= 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
// check({ fooThrow(len >= 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
// check({ fooThrow(len >= 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
// check({ fooThrow(len >= 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "fooThrow.");
// check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
// check({ fooThrow(len >= 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow.");
// check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
// check({ fooThrow(len > 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
// check({ fooThrow(len > 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
// check({ fooThrow(len > 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
// check({ fooThrow(len > 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
// check({ fooThrow(len > 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "makeS(1).get(1).fooThrow.dtor(1).");
// check({ fooThrow(len > 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
// check({ fooThrow(len > 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow.");
// check({ fooThrow(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).fooThrow.dtor(1).");

// temporaries in each conditions
check({ foo(len == 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, "makeS(1).get(1).makeS(2).get(2).foo.dtor(2).dtor(1).");
Expand All @@ -4051,56 +4051,6 @@ void test14696(int len = 2)
check({ foo(len != 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, "foo.");
}

/**********************************/
// 14708

bool dtor14708 = false;

struct S14708
{
int n;

void* get(void* p = null)
{
return null;
}

~this()
{
//printf("dtor\n");
dtor14708 = true;
}
}

S14708 makeS14708(int n)
{
return S14708(n);
}

void foo14708(void* x)
{
throw new Exception("fail!");
}

void bar14708()
{
foo14708(makeS14708(1).get());
// A temporary is allocated on stack for the
// return value from makeS(1).
// When foo throws exception, it's dtor should be called
// during unwinding stack, but it does not happen in Win64.
}

void test14708()
{
try
{
bar14708();
} catch (Exception e) {}
assert(dtor14708); // fails!
}

/**********************************/
// 14838

int test14838() pure nothrow @safe
Expand Down Expand Up @@ -4270,7 +4220,6 @@ int main()
test13095();
test14264();
test14696();
test14708();
test14838();

printf("Success\n");
Expand Down

0 comments on commit ef854c3

Please sign in to comment.