Created
February 19, 2014 19:15
-
-
Save jpf91/9099430 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From ba8e51dd4f00f4258564f6a0ab2033a0b635682a Mon Sep 17 00:00:00 2001 | |
Message-Id: <ba8e51dd4f00f4258564f6a0ab2033a0b635682a.1392836625.git.johannespfau@gmail.com> | |
From: Johannes Pfau <[email protected]> | |
Date: Wed, 19 Feb 2014 20:01:55 +0100 | |
Subject: [PATCH] Add @nogc attribute | |
Conflicts: | |
src/nogc.c | |
--- | |
src/attrib.c | 1 + | |
src/declaration.h | 5 +++-- | |
src/func.c | 4 ++++ | |
src/idgen.c | 1 + | |
src/mtype.c | 16 +++++++++++++++- | |
src/nogc.c | 41 ++++++++++++++++++++++++----------------- | |
src/parse.c | 3 +++ | |
7 files changed, 51 insertions(+), 20 deletions(-) | |
diff --git a/src/attrib.c b/src/attrib.c | |
index 063931e..c40d486 100644 | |
--- a/src/attrib.c | |
+++ b/src/attrib.c | |
@@ -495,6 +495,7 @@ const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc) | |
{ STCtrusted, TOKat, "trusted" }, | |
{ STCsystem, TOKat, "system" }, | |
{ STCdisable, TOKat, "disable" }, | |
+ { STCnogc, TOKat, "nogc" }, | |
{ 0, TOKreserved } | |
}; | |
diff --git a/src/declaration.h b/src/declaration.h | |
index 7bed070..f056561 100644 | |
--- a/src/declaration.h | |
+++ b/src/declaration.h | |
@@ -73,7 +73,7 @@ enum PURE; | |
// but not typed as "shared" | |
#define STCwild 0x80000000LL // for "wild" type constructor | |
#define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild) | |
-#define STC_FUNCATTR (STCref | STCnothrow | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem) | |
+#define STC_FUNCATTR (STCref | STCnothrow | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem | STCnogc) | |
#define STCproperty 0x100000000LL | |
#define STCsafe 0x200000000LL | |
@@ -85,12 +85,13 @@ enum PURE; | |
#define STCnodefaultctor 0x8000000000LL // must be set inside constructor | |
#define STCtemp 0x10000000000LL // temporary variable | |
#define STCrvalue 0x20000000000LL // force rvalue for variables | |
+#define STCnogc 0x40000000000LL // force rvalue for variables | |
const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | | |
STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias | | |
STCout | STCin | | |
STCmanifest | STCimmutable | STCshared | STCwild | STCnothrow | STCpure | STCref | STCtls | | |
- STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable); | |
+ STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable | STCnogc); | |
struct Match | |
{ | |
diff --git a/src/func.c b/src/func.c | |
index 0f11d84..9394523 100644 | |
--- a/src/func.c | |
+++ b/src/func.c | |
@@ -469,6 +469,7 @@ void FuncDeclaration::semantic(Scope *sc) | |
if (tf->trust == TRUSTsafe) sc->stc |= STCsafe; | |
if (tf->trust == TRUSTsystem) sc->stc |= STCsystem; | |
if (tf->trust == TRUSTtrusted) sc->stc |= STCtrusted; | |
+ if (tf->gcuse == GCUSEnogc) sc->stc |= STCnogc; | |
if (isCtorDeclaration()) | |
{ | |
@@ -1118,6 +1119,9 @@ Ldone: | |
if (f->purity == PUREimpure) // purity not specified | |
flags |= FUNCFLAGpurityInprocess; | |
+ if (f->gcuse == GCUSEdefault) | |
+ flags |= FUNCFLAGgcuseInprocess; | |
+ | |
if (f->trust == TRUSTdefault) | |
flags |= FUNCFLAGsafetyInprocess; | |
diff --git a/src/idgen.c b/src/idgen.c | |
index 150ec55..ffbbc1d 100644 | |
--- a/src/idgen.c | |
+++ b/src/idgen.c | |
@@ -152,6 +152,7 @@ Msgtable msgtable[] = | |
{ "trusted" }, | |
{ "system" }, | |
{ "disable" }, | |
+ { "nogc" }, | |
// For inline assembler | |
{ "___out", "out" }, | |
diff --git a/src/mtype.c b/src/mtype.c | |
index 9c19911..d92349d 100644 | |
--- a/src/mtype.c | |
+++ b/src/mtype.c | |
@@ -5129,6 +5129,7 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, L | |
this->inuse = 0; | |
this->isnothrow = false; | |
this->purity = PUREimpure; | |
+ this->gcuse = GCUSEgc; | |
this->isproperty = false; | |
this->isref = false; | |
this->iswild = 0; | |
@@ -5140,6 +5141,8 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, L | |
this->isnothrow = true; | |
if (stc & STCproperty) | |
this->isproperty = true; | |
+ if (stc & STCnogc) | |
+ this->gcuse = GCUSEnogc; | |
if (stc & STCref) | |
this->isref = true; | |
@@ -5329,6 +5332,11 @@ Lcovariant: | |
if (!t1->isnothrow && t2->isnothrow) | |
stc |= STCnothrow; | |
+ /* Can convert nogc/default to gc | |
+ */ | |
+ if (t1->gcuse <= GCUSEgc && t2->gcuse >= GCUSEnogc) | |
+ stc |= STCnogc; | |
+ | |
/* Can convert safe/trusted to system | |
*/ | |
if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted) | |
@@ -5441,6 +5449,8 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) | |
if (sc->stc & STCpure) | |
tf->purity = PUREfwdref; | |
+ if (sc->stc & STCnogc) | |
+ tf->gcuse = GCUSEnogc; | |
if (sc->stc & STCnothrow) | |
tf->isnothrow = true; | |
if (sc->stc & STCref) | |
@@ -6147,13 +6157,15 @@ Type *TypeFunction::addStorageClass(StorageClass stc) | |
TypeFunction *t = (TypeFunction *)Type::addStorageClass(stc); | |
if ((stc & STCpure && !t->purity) || | |
(stc & STCnothrow && !t->isnothrow) || | |
- (stc & STCsafe && t->trust < TRUSTtrusted)) | |
+ (stc & STCsafe && t->trust < TRUSTtrusted) || | |
+ (stc & STCnogc && t->gcuse < GCUSEnogc)) | |
{ | |
// Klunky to change these | |
TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0); | |
tf->mod = t->mod; | |
tf->fargs = fargs; | |
tf->purity = t->purity; | |
+ tf->gcuse = t->gcuse; | |
tf->isnothrow = t->isnothrow; | |
tf->isproperty = t->isproperty; | |
tf->isref = t->isref; | |
@@ -6163,6 +6175,8 @@ Type *TypeFunction::addStorageClass(StorageClass stc) | |
if (stc & STCpure) | |
tf->purity = PUREfwdref; | |
+ if (stc & STCnogc) | |
+ tf->gcuse = GCUSEnogc; | |
if (stc & STCnothrow) | |
tf->isnothrow = true; | |
if (stc & STCsafe) | |
diff --git a/src/nogc.c b/src/nogc.c | |
index c932702..baf2a51 100644 | |
--- a/src/nogc.c | |
+++ b/src/nogc.c | |
@@ -34,25 +34,35 @@ public: | |
if (e->e1 && e->e1->op == TOKvar) | |
{ | |
VarExp *ve = (VarExp*)e->e1; | |
- if (ve->var && ve->var->isFuncDeclaration() && ve->var->isFuncDeclaration()->ident) | |
+ if (ve->var && ve->var->isFuncDeclaration() && ve->var->isFuncDeclaration()) | |
{ | |
- Identifier *ident = ve->var->isFuncDeclaration()->ident; | |
- | |
- if (strcmp(ident->toChars(), "_adSortChar") == 0 || | |
- strcmp(ident->toChars(), "_adSortWchar") == 0) | |
+ FuncDeclaration *decl = ve->var->isFuncDeclaration(); | |
+ Identifier *ident = decl->ident; | |
+ if (ident) | |
{ | |
- if (func->setGCUse(e->loc, "'sort' may cause gc allocation")) | |
+ if (strcmp(ident->toChars(), "_adSortChar") == 0 || | |
+ strcmp(ident->toChars(), "_adSortWchar") == 0) | |
{ | |
- e->error("Can not use 'sort' in @nogc code"); | |
+ if (func->setGCUse(e->loc, "'sort' may cause gc allocation")) | |
+ { | |
+ e->error("Can not use 'sort' in @nogc code"); | |
+ } | |
+ return; | |
} | |
- } | |
- if (ident == Id::adDup) | |
- { | |
- if (func->setGCUse(e->loc, "'dup' causes gc allocation")) | |
+ if (ident == Id::adDup) | |
{ | |
- e->error("Can not use 'dup' in @nogc code"); | |
+ if (func->setGCUse(e->loc, "'dup' causes gc allocation")) | |
+ { | |
+ e->error("Can not use 'dup' in @nogc code"); | |
+ } | |
+ return; | |
} | |
} | |
+ //TODO:sc->func && !(sc->flags & SCOPEctfe) | |
+ if (!decl->isNOGC() && func->setGCUse()) | |
+ { | |
+ e->error("Can not call '@gc' function from '@nogc' function"); | |
+ } | |
} | |
} | |
} | |
@@ -276,9 +286,6 @@ public: | |
void checkGC(FuncDeclaration *func, Statement *stmt) | |
{ | |
- if (global.params.vgc) | |
- { | |
- GCStatementVisitor gcv(func); | |
- walkPostorder(stmt, &gcv); | |
- } | |
+ GCStatementVisitor gcv(func); | |
+ walkPostorder(stmt, &gcv); | |
} | |
diff --git a/src/parse.c b/src/parse.c | |
index 0b078fe..b7f63d4 100644 | |
--- a/src/parse.c | |
+++ b/src/parse.c | |
@@ -763,6 +763,7 @@ void Parser::composeStorageClass(StorageClass stc) | |
u &= STCsafe | STCsystem | STCtrusted; | |
if (u & (u - 1)) | |
error("conflicting attribute @%s", token.toChars()); | |
+ u &= STCnogc; | |
} | |
/*********************************************** | |
@@ -793,6 +794,8 @@ StorageClass Parser::parseAttribute(Expressions **pudas) | |
stc = STCsystem; | |
else if (token.ident == Id::disable) | |
stc = STCdisable; | |
+ else if (token.ident == Id::nogc) | |
+ stc = STCnogc; | |
else | |
{ // Allow identifier, template instantiation, or function call | |
Expression *exp = parsePrimaryExp(); | |
-- | |
1.9.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment