fixes #441 :: Synchronized does not work during Exception-unwinding; thanks rawler

This commit is contained in:
Moritz Warning
2010-11-14 20:21:09 +01:00
parent 71535ffd1c
commit 4b97c6b6a2
2 changed files with 39 additions and 24 deletions

View File

@@ -1495,19 +1495,17 @@ void FuncDeclaration::semantic3(Scope *sc)
// we do not want to rerun semantics on the whole function, so we
// manually adjust all labels in the function that currently don't
// have an enclosingScopeExit to use the new SynchronizedStatement
SynchronizedStatement* s = new SynchronizedStatement(loc, sync, NULL);
s->semantic(sc2);
s->body = fbody;
Statement* nbody = new PeelStatement(fbody);
nbody = new SynchronizedStatement(loc, sync, nbody);
nbody = nbody->semantic(sc2);
// LDC
LabelMap::iterator it, end = labmap.end();
for (it = labmap.begin(); it != end; ++it)
if (it->second->enclosingScopeExit == NULL)
it->second->enclosingScopeExit = s;
it->second->enclosingScopeExit = nbody;
a = new Statements;
a->push(s);
fbody = new CompoundStatement(0, a);
fbody = nbody;
}
}

View File

@@ -12,6 +12,12 @@
#include <stdlib.h>
#include <assert.h>
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
#include <pthread.h> // Needs pthread_mutex_t for os_critsecsize
#elif _WIN32
#include <windows.h>
#endif
#include "rmem.h"
#include "statement.h"
@@ -29,7 +35,22 @@
#include "template.h"
#include "attrib.h"
extern int os_critsecsize();
/***********************************
* Return size of OS critical section.
*/
#if _WIN32
int os_critsecsize()
{
return sizeof(CRITICAL_SECTION);
}
#endif
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
int os_critsecsize()
{
return sizeof(pthread_mutex_t);
}
#endif
/******************************** Statement ***************************/
@@ -3752,7 +3773,6 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
exp = exp->semantic(sc);
}
#if 0
/* Rewrite as:
* auto tmp = exp;
* _d_monitorenter(tmp);
@@ -3765,12 +3785,16 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
Statements *cs = new Statements();
cs->push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorenter);
Parameters* enterargs = new Parameters;
enterargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(enterargs, Type::tvoid, Id::monitorenter);
Expression *e = new CallExp(loc, new VarExp(loc, fdenter), new VarExp(loc, tmp));
e->type = Type::tvoid; // do not run semantic on e
cs->push(new ExpStatement(loc, e));
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorexit);
Parameters* exitargs = new Parameters;
exitargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(exitargs, Type::tvoid, Id::monitorexit);
e = new CallExp(loc, new VarExp(loc, fdexit), new VarExp(loc, tmp));
e->type = Type::tvoid; // do not run semantic on e
Statement *s = new ExpStatement(loc, e);
@@ -3779,9 +3803,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
s = new CompoundStatement(loc, cs);
return s->semantic(sc);
#endif
}
#if 0
else
{ /* Generate our own critical section, then rewrite as:
* __gshared byte[CriticalSection.sizeof] critsec;
@@ -3796,14 +3818,18 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
Statements *cs = new Statements();
cs->push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalenter);
Parameters* enterargs = new Parameters;
enterargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(enterargs, Type::tvoid, Id::criticalenter);
Expression *e = new DotIdExp(loc, new VarExp(loc, tmp), Id::ptr);
e = e->semantic(sc);
e = new CallExp(loc, new VarExp(loc, fdenter), e);
e->type = Type::tvoid; // do not run semantic on e
cs->push(new ExpStatement(loc, e));
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalexit);
Parameters* exitargs = new Parameters;
exitargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(exitargs, Type::tvoid, Id::criticalexit);
e = new DotIdExp(loc, new VarExp(loc, tmp), Id::ptr);
e = e->semantic(sc);
e = new CallExp(loc, new VarExp(loc, fdexit), e);
@@ -3815,15 +3841,6 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
s = new CompoundStatement(loc, cs);
return s->semantic(sc);
}
#endif
if (body)
{
Statement* oldScopeExit = sc->enclosingScopeExit;
sc->enclosingScopeExit = this;
body = body->semantic(sc);
sc->enclosingScopeExit = oldScopeExit;
}
return this;
}
int SynchronizedStatement::hasBreak()