-
-
Notifications
You must be signed in to change notification settings - Fork 683
Issue 9766 - align(n) with n compile-time constant #5750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,18 +78,25 @@ public: | |
| * If the returned scope != sc, the caller should pop | ||
| * the scope after it used. | ||
| */ | ||
| static Scope* createNewScope(Scope* sc, StorageClass stc, LINK linkage, Prot protection, int explicitProtection, structalign_t structalign, PINLINE inlining) | ||
| static Scope* createNewScope(Scope* sc, StorageClass stc, LINK linkage, | ||
| Prot protection, int explicitProtection, AlignDeclaration aligndecl, | ||
| PINLINE inlining) | ||
| { | ||
| Scope* sc2 = sc; | ||
| if (stc != sc.stc || linkage != sc.linkage || !protection.isSubsetOf(sc.protection) || explicitProtection != sc.explicitProtection || structalign != sc.structalign || inlining != sc.inlining) | ||
| if (stc != sc.stc || | ||
| linkage != sc.linkage || | ||
| !protection.isSubsetOf(sc.protection) || | ||
| explicitProtection != sc.explicitProtection || | ||
| aligndecl !is sc.aligndecl || | ||
| inlining != sc.inlining) | ||
| { | ||
| // create new one for changes | ||
| sc2 = sc.copy(); | ||
| sc2.stc = stc; | ||
| sc2.linkage = linkage; | ||
| sc2.protection = protection; | ||
| sc2.explicitProtection = explicitProtection; | ||
| sc2.structalign = structalign; | ||
| sc2.aligndecl = aligndecl; | ||
| sc2.inlining = inlining; | ||
| } | ||
| return sc2; | ||
|
|
@@ -352,7 +359,9 @@ public: | |
| scstc &= ~(STCsafe | STCtrusted | STCsystem); | ||
| scstc |= stc; | ||
| //printf("scstc = x%llx\n", scstc); | ||
| return createNewScope(sc, scstc, sc.linkage, sc.protection, sc.explicitProtection, sc.structalign, sc.inlining); | ||
| return createNewScope(sc, scstc, sc.linkage, | ||
| sc.protection, sc.explicitProtection, sc.aligndecl, | ||
| sc.inlining); | ||
| } | ||
|
|
||
| override final bool oneMember(Dsymbol* ps, Identifier ident) | ||
|
|
@@ -499,7 +508,9 @@ public: | |
|
|
||
| override Scope* newScope(Scope* sc) | ||
| { | ||
| return createNewScope(sc, sc.stc, this.linkage, sc.protection, sc.explicitProtection, sc.structalign, sc.inlining); | ||
| return createNewScope(sc, sc.stc, this.linkage, | ||
| sc.protection, sc.explicitProtection, sc.aligndecl, | ||
| sc.inlining); | ||
| } | ||
|
|
||
| override const(char)* toChars() const | ||
|
|
@@ -563,7 +574,9 @@ public: | |
| { | ||
| if (pkg_identifiers) | ||
| semantic(sc); | ||
| return createNewScope(sc, sc.stc, sc.linkage, this.protection, 1, sc.structalign, sc.inlining); | ||
| return createNewScope(sc, sc.stc, sc.linkage, | ||
| this.protection, 1, sc.aligndecl, | ||
| sc.inlining); | ||
| } | ||
|
|
||
| override void addMember(Scope* sc, ScopeDsymbol sds) | ||
|
|
@@ -611,23 +624,91 @@ public: | |
| extern (C++) final class AlignDeclaration : AttribDeclaration | ||
| { | ||
| public: | ||
| uint salign; | ||
| Expression ealign; | ||
| structalign_t salign = STRUCTALIGN_DEFAULT; | ||
|
|
||
| extern (D) this(uint sa, Dsymbols* decl) | ||
| extern (D) this(Loc loc, Expression ealign, Dsymbols* decl) | ||
| { | ||
| super(decl); | ||
| salign = sa; | ||
| this.loc = loc; | ||
| this.ealign = ealign; | ||
| } | ||
|
|
||
| override Dsymbol syntaxCopy(Dsymbol s) | ||
| { | ||
| assert(!s); | ||
| return new AlignDeclaration(salign, Dsymbol.arraySyntaxCopy(decl)); | ||
| return new AlignDeclaration(loc, | ||
| ealign.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl)); | ||
| } | ||
|
|
||
| override Scope* newScope(Scope* sc) | ||
| { | ||
| return createNewScope(sc, sc.stc, sc.linkage, sc.protection, sc.explicitProtection, this.salign, sc.inlining); | ||
| return createNewScope(sc, sc.stc, sc.linkage, | ||
| sc.protection, sc.explicitProtection, this, | ||
| sc.inlining); | ||
| } | ||
|
|
||
| override void setScope(Scope* sc) | ||
| { | ||
| //printf("AlignDeclaration::setScope() %p\n", this); | ||
| if (ealign && decl) | ||
| Dsymbol.setScope(sc); // for forward reference | ||
| return AttribDeclaration.setScope(sc); | ||
| } | ||
|
|
||
| override void semantic2(Scope* sc) | ||
| { | ||
| getAlignment(); | ||
| super.semantic2(sc); | ||
| } | ||
|
|
||
| structalign_t getAlignment() | ||
| { | ||
| if (!ealign) | ||
| return STRUCTALIGN_DEFAULT; | ||
|
|
||
| if (auto sc = _scope) | ||
| { | ||
| _scope = null; | ||
|
|
||
| sc = sc.startCTFE(); | ||
| ealign = ealign.semantic(sc); | ||
| ealign = resolveProperties(sc, ealign); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems to me ctfeInterpret() should be put here.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and then just do toInteger(), which will take care of most of the cases below. Then, just have one: should do it. |
||
| sc = sc.endCTFE(); | ||
|
|
||
| auto errorPositiveInteger() | ||
| { | ||
| .error(loc, "positive integer expected, not %s", ealign.toChars()); | ||
| return STRUCTALIGN_DEFAULT; | ||
| } | ||
|
|
||
| if (ealign.op == TOKerror) | ||
| return STRUCTALIGN_DEFAULT; | ||
| if (!ealign.type) | ||
| return errorPositiveInteger(); | ||
| Type tb = ealign.type.toBasetype(); | ||
| if (!tb.isintegral()) | ||
| return errorPositiveInteger(); | ||
| if (tb.ty == Tchar || tb.ty == Twchar || tb.ty == Tdchar || tb.ty == Tbool) | ||
| return errorPositiveInteger(); | ||
|
|
||
| ealign = ealign.ctfeInterpret(); | ||
| if (ealign.op == TOKerror) | ||
| return STRUCTALIGN_DEFAULT; | ||
|
|
||
| auto n = ealign.toInteger(); | ||
| if (n < 1 || structalign_t.max < n) | ||
| return errorPositiveInteger(); | ||
|
|
||
| if (n & (n - 1)) | ||
| { | ||
| .error(loc, "alignment must be a power of 2, not %u", cast(structalign_t)n); | ||
| return STRUCTALIGN_DEFAULT; | ||
| } | ||
|
|
||
| salign = cast(structalign_t)n; | ||
| } | ||
| return salign; | ||
| } | ||
|
|
||
| override void accept(Visitor v) | ||
|
|
@@ -642,7 +723,6 @@ extern (C++) final class AnonDeclaration : AttribDeclaration | |
| { | ||
| public: | ||
| bool isunion; | ||
| structalign_t alignment; | ||
| int sem; // 1 if successful semantic() | ||
| uint anonoffset; // offset of anonymous struct | ||
| uint anonstructsize; // size of anonymous struct | ||
|
|
@@ -663,22 +743,23 @@ public: | |
|
|
||
| override void setScope(Scope* sc) | ||
| { | ||
| super.setScope(sc); | ||
| alignment = sc.structalign; | ||
| if (decl) | ||
| Dsymbol.setScope(sc); | ||
| return AttribDeclaration.setScope(sc); | ||
| } | ||
|
|
||
| override void semantic(Scope* sc) | ||
| { | ||
| //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); | ||
| assert(sc.parent); | ||
| Dsymbol p = sc.parent.pastMixin(); | ||
| AggregateDeclaration ad = p.isAggregateDeclaration(); | ||
| auto p = sc.parent.pastMixin(); | ||
| auto ad = p.isAggregateDeclaration(); | ||
| if (!ad) | ||
| { | ||
| .error(loc, "%s can only be a part of an aggregate, not %s %s", kind(), p.kind(), p.toChars()); | ||
| return; | ||
| } | ||
| alignment = sc.structalign; | ||
|
|
||
| if (decl) | ||
| { | ||
| sc = sc.push(); | ||
|
|
@@ -746,6 +827,9 @@ public: | |
| anonalignsize = 1; | ||
| } | ||
|
|
||
| assert(_scope); | ||
| auto alignment = _scope.alignment(); | ||
|
|
||
| /* Given the anon 'member's size and alignment, | ||
| * go ahead and place it. | ||
| */ | ||
|
|
@@ -833,7 +917,9 @@ public: | |
| else if (e.isBool(false)) | ||
| inlining = PINLINEnever; | ||
| } | ||
| return createNewScope(sc, sc.stc, sc.linkage, sc.protection, sc.explicitProtection, sc.structalign, inlining); | ||
| return createNewScope(sc, sc.stc, sc.linkage, | ||
| sc.protection, sc.explicitProtection, sc.aligndecl, | ||
| inlining); | ||
| } | ||
| return sc; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -143,7 +143,7 @@ struct Scope | |
| size_t fieldinit_dim; | ||
|
|
||
| // alignment for struct members | ||
| structalign_t structalign = STRUCTALIGN_DEFAULT; | ||
| AlignDeclaration aligndecl; | ||
|
|
||
| // linkage for external functions | ||
| LINK linkage = LINKd; | ||
|
|
@@ -722,7 +722,7 @@ struct Scope | |
| this.scontinue = sc.scontinue; | ||
| this.fes = sc.fes; | ||
| this.callsc = sc.callsc; | ||
| this.structalign = sc.structalign; | ||
| this.aligndecl = sc.aligndecl; | ||
| this.func = sc.func; | ||
| this.slabel = sc.slabel; | ||
| this.linkage = sc.linkage; | ||
|
|
@@ -745,4 +745,12 @@ struct Scope | |
| this.prevAnchor = sc.prevAnchor; | ||
| this.userAttribDecl = sc.userAttribDecl; | ||
| } | ||
|
|
||
| structalign_t alignment() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This duplicates logic found above. Merge into |
||
| { | ||
| if (aligndecl) | ||
| return aligndecl.getAlignment(); | ||
| else | ||
| return STRUCTALIGN_DEFAULT; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This calls
Dsymbol.setScope()followed byAttribDeclaration.setScope()which is surely a bug.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No.
AttribDeclaration.setScopedoes not set_scopeintentionally because it's not used for other attributes - ProtDeclaration, ConditionDeclaration + (VersionCondition, DebugCondition), etc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok