Skip to content

Instantly share code, notes, and snippets.

@jpf91
Created February 19, 2014 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpf91/9099430 to your computer and use it in GitHub Desktop.
Save jpf91/9099430 to your computer and use it in GitHub Desktop.
From ba8e51dd4f00f4258564f6a0ab2033a0b635682a Mon Sep 17 00:00:00 2001
Message-Id: <ba8e51dd4f00f4258564f6a0ab2033a0b635682a.1392836625.git.johannespfau@gmail.com>
From: Johannes Pfau <johannespfau@gmail.com>
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