Skip to content

Commit

Permalink
Issue 9766 - align(n) with n compile-time constant
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw committed Jul 23, 2017
1 parent b1d3a21 commit 5b42a07
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 89 deletions.
110 changes: 95 additions & 15 deletions src/attrib.c
Expand Up @@ -72,15 +72,15 @@ int AttribDeclaration::apply(Dsymbol_apply_ft_t fp, void *param)
*/
Scope *AttribDeclaration::createNewScope(Scope *sc,
StorageClass stc, LINK linkage, CPPMANGLE cppmangle, Prot protection,
int explicitProtection, structalign_t structalign, PINLINE inlining)
int explicitProtection, AlignDeclaration *aligndecl, PINLINE inlining)
{
Scope *sc2 = sc;
if (stc != sc->stc ||
linkage != sc->linkage ||
cppmangle != sc->cppmangle ||
!protection.isSubsetOf(sc->protection) ||
explicitProtection != sc->explicitProtection ||
structalign != sc->structalign ||
aligndecl != sc->aligndecl ||
inlining != sc->inlining)
{
// create new one for changes
Expand All @@ -90,7 +90,7 @@ Scope *AttribDeclaration::createNewScope(Scope *sc,
sc2->cppmangle = cppmangle;
sc2->protection = protection;
sc2->explicitProtection = explicitProtection;
sc2->structalign = structalign;
sc2->aligndecl = aligndecl;
sc2->inlining = inlining;
}
return sc2;
Expand Down Expand Up @@ -393,7 +393,9 @@ Scope *StorageClassDeclaration::newScope(Scope *sc)
scstc |= stc;
//printf("scstc = x%llx\n", scstc);

return createNewScope(sc, scstc, sc->linkage, sc->cppmangle, sc->protection, sc->explicitProtection, sc->structalign, sc->inlining);
return createNewScope(sc, scstc, sc->linkage, sc->cppmangle,
sc->protection, sc->explicitProtection, sc->aligndecl,
sc->inlining);
}

/********************************* DeprecatedDeclaration ****************************/
Expand Down Expand Up @@ -491,7 +493,9 @@ Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s)

Scope *LinkDeclaration::newScope(Scope *sc)
{
return createNewScope(sc, sc->stc, this->linkage, sc->cppmangle, sc->protection, sc->explicitProtection, sc->structalign, sc->inlining);
return createNewScope(sc, sc->stc, this->linkage, sc->cppmangle,
sc->protection, sc->explicitProtection, sc->aligndecl,
sc->inlining);
}

const char *LinkDeclaration::toChars()
Expand All @@ -516,7 +520,9 @@ Dsymbol *CPPMangleDeclaration::syntaxCopy(Dsymbol *s)

Scope *CPPMangleDeclaration::newScope(Scope *sc)
{
return createNewScope(sc, sc->stc, LINKcpp, this->cppmangle, sc->protection, sc->explicitProtection, sc->structalign, sc->inlining);
return createNewScope(sc, sc->stc, LINKcpp, this->cppmangle,
sc->protection, sc->explicitProtection, sc->aligndecl,
sc->inlining);
}

const char *CPPMangleDeclaration::toChars()
Expand Down Expand Up @@ -569,7 +575,9 @@ Scope *ProtDeclaration::newScope(Scope *sc)
{
if (pkg_identifiers)
semantic(sc);
return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle, this->protection, 1, sc->structalign, sc->inlining);
return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
this->protection, 1, sc->aligndecl,
sc->inlining);
}

void ProtDeclaration::addMember(Scope *sc, ScopeDsymbol *sds)
Expand Down Expand Up @@ -612,21 +620,89 @@ const char *ProtDeclaration::toPrettyChars(bool)

/********************************* AlignDeclaration ****************************/

AlignDeclaration::AlignDeclaration(unsigned sa, Dsymbols *decl)
AlignDeclaration::AlignDeclaration(Loc loc, Expression *ealign, Dsymbols *decl)
: AttribDeclaration(decl)
{
salign = sa;
this->loc = loc;
this->ealign = ealign;
this->salign = STRUCTALIGN_DEFAULT;
}

Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s)
{
assert(!s);
return new AlignDeclaration(salign, Dsymbol::arraySyntaxCopy(decl));
return new AlignDeclaration(loc,
ealign->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl));
}

Scope *AlignDeclaration::newScope(Scope *sc)
{
return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle, sc->protection, sc->explicitProtection, this->salign, sc->inlining);
return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
sc->protection, sc->explicitProtection, this,
sc->inlining);
}

void AlignDeclaration::setScope(Scope *sc)
{
//printf("AlignDeclaration::setScope() %p\n", this);
if (ealign && decl)
Dsymbol::setScope(sc); // for forward reference
return AttribDeclaration::setScope(sc);
}

void AlignDeclaration::semantic2(Scope *sc)
{
getAlignment();
AttribDeclaration::semantic2(sc);
}

static structalign_t errorPositiveInteger(Loc loc, Expression *ealign)
{
error(loc, "positive integer expected, not %s", ealign->toChars());
return STRUCTALIGN_DEFAULT;
}

structalign_t AlignDeclaration::getAlignment()
{
if (!ealign)
return STRUCTALIGN_DEFAULT;

if (Scope *sc = _scope)
{
_scope = NULL;

sc = sc->startCTFE();
ealign = ealign->semantic(sc);
ealign = resolveProperties(sc, ealign);
sc = sc->endCTFE();

if (ealign->op == TOKerror)
return STRUCTALIGN_DEFAULT;
if (!ealign->type)
return errorPositiveInteger(loc, ealign);
Type *tb = ealign->type->toBasetype();
if (!tb->isintegral())
return errorPositiveInteger(loc, ealign);
if (tb->ty == Tchar || tb->ty == Twchar || tb->ty == Tdchar || tb->ty == Tbool)
return errorPositiveInteger(loc, ealign);

ealign = ealign->ctfeInterpret();
if (ealign->op == TOKerror)
return STRUCTALIGN_DEFAULT;

sinteger_t n = ealign->toInteger();
if (n < 1 || STRUCTALIGN_DEFAULT < n)
return errorPositiveInteger(loc, ealign);

if (n & (n - 1))
{
::error(loc, "alignment must be a power of 2, not %u", (structalign_t)n);
return STRUCTALIGN_DEFAULT;
}

salign = (structalign_t)n;
}
return salign;
}

/********************************* AnonDeclaration ****************************/
Expand All @@ -635,7 +711,6 @@ AnonDeclaration::AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl)
: AttribDeclaration(decl)
{
this->loc = loc;
this->alignment = 0;
this->isunion = isunion;
this->sem = 0;
this->anonoffset = 0;
Expand All @@ -652,8 +727,9 @@ Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s)
void AnonDeclaration::setScope(Scope *sc)
{
//printf("AnonDeclaration::setScope() %p\n", this);
if (decl)
Dsymbol::setScope(sc);
AttribDeclaration::setScope(sc);
alignment = sc->structalign;
}

void AnonDeclaration::semantic(Scope *sc)
Expand All @@ -671,7 +747,6 @@ void AnonDeclaration::semantic(Scope *sc)
return;
}

alignment = sc->structalign;
if (decl)
{
sc = sc->push();
Expand Down Expand Up @@ -743,6 +818,9 @@ void AnonDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset
anonalignsize = 1;
}

assert(_scope);
structalign_t alignment = _scope->alignment();

/* Given the anon 'member's size and alignment,
* go ahead and place it.
*/
Expand Down Expand Up @@ -818,7 +896,9 @@ Scope *PragmaDeclaration::newScope(Scope *sc)
inlining = PINLINEnever;
}

return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle, sc->protection, sc->explicitProtection, sc->structalign, inlining);
return createNewScope(sc, sc->stc, sc->linkage, sc->cppmangle,
sc->protection, sc->explicitProtection, sc->aligndecl,
inlining);
}
return sc;
}
Expand Down
11 changes: 7 additions & 4 deletions src/attrib.h
Expand Up @@ -37,7 +37,7 @@ class AttribDeclaration : public Dsymbol
int apply(Dsymbol_apply_ft_t fp, void *param);
static Scope *createNewScope(Scope *sc,
StorageClass newstc, LINK linkage, CPPMANGLE cppmangle, Prot protection,
int explictProtection, structalign_t structalign, PINLINE inlining);
int explictProtection, AlignDeclaration *aligndecl, PINLINE inlining);
virtual Scope *newScope(Scope *sc);
void addMember(Scope *sc, ScopeDsymbol *sds);
void setScope(Scope *sc);
Expand Down Expand Up @@ -130,19 +130,22 @@ class ProtDeclaration : public AttribDeclaration
class AlignDeclaration : public AttribDeclaration
{
public:
unsigned salign;
Expression *ealign;
structalign_t salign;

AlignDeclaration(unsigned sa, Dsymbols *decl);
AlignDeclaration(Loc loc, Expression *ealign, Dsymbols *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
Scope *newScope(Scope *sc);
void setScope(Scope *sc);
void semantic2(Scope *sc);
structalign_t getAlignment();
void accept(Visitor *v) { v->visit(this); }
};

class AnonDeclaration : public AttribDeclaration
{
public:
bool isunion;
structalign_t alignment;
int sem; // 1 if successful semantic()
unsigned anonoffset; // offset of anonymous struct
unsigned anonstructsize; // size of anonymous struct
Expand Down
6 changes: 3 additions & 3 deletions src/class.c
Expand Up @@ -586,7 +586,7 @@ void ClassDeclaration::semantic(Scope *sc)
}
sc2->protection = Prot(PROTpublic);
sc2->explicitProtection = 0;
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->aligndecl = NULL;
sc2->userAttribDecl = NULL;

/* Set scope so if there are forward references, we still might be able to
Expand Down Expand Up @@ -700,7 +700,7 @@ void ClassDeclaration::semantic(Scope *sc)
}
sc2->protection = Prot(PROTpublic);
sc2->explicitProtection = 0;
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->aligndecl = NULL;
sc2->userAttribDecl = NULL;

for (size_t i = 0; i < members->dim; i++)
Expand Down Expand Up @@ -1634,7 +1634,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc2->linkage = LINKobjc;
sc2->protection = Prot(PROTpublic);
sc2->explicitProtection = 0;
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->aligndecl = NULL;
sc2->userAttribDecl = NULL;

finalizeSize(sc2);
Expand Down
2 changes: 1 addition & 1 deletion src/declaration.c
Expand Up @@ -886,7 +886,7 @@ void VarDeclaration::semantic(Scope *sc)
/* If scope's alignment is the default, use the type's alignment,
* otherwise the scope overrrides.
*/
alignment = sc->structalign;
alignment = sc->alignment();
if (alignment == STRUCTALIGN_DEFAULT)
alignment = type->alignment(); // use type's alignment

Expand Down
2 changes: 1 addition & 1 deletion src/func.c
Expand Up @@ -1352,7 +1352,7 @@ void FuncDeclaration::semantic3(Scope *sc)
STCproperty | STCnothrow | STCpure | STCsafe | STCtrusted | STCsystem);
sc2->protection = Prot(PROTpublic);
sc2->explicitProtection = 0;
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->aligndecl = NULL;
if (this->ident != Id::require && this->ident != Id::ensure)
sc2->flags = sc->flags & ~SCOPEcontract;
sc2->flags &= ~SCOPEcompile;
Expand Down
6 changes: 3 additions & 3 deletions src/hdrgen.c
Expand Up @@ -1251,10 +1251,10 @@ class PrettyPrintVisitor : public Visitor

void visit(AlignDeclaration *d)
{
if (d->salign == STRUCTALIGN_DEFAULT)
buf->printf("align");
if (!d->ealign)
buf->printf("align ");
else
buf->printf("align (%d)", d->salign);
buf->printf("align (%s)", d->ealign->toChars());
visit((AttribDeclaration *)d);
}

Expand Down

0 comments on commit 5b42a07

Please sign in to comment.