Skip to content
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

Merge upstream stable (v2.098.0+) #3844

Merged
merged 5 commits into from
Oct 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion dmd/aggregate.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import dmd.aliasthis;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
import dmd.declaration;
import dmd.dscope;
import dmd.dstruct;
Expand Down Expand Up @@ -536,7 +537,10 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
addu(ofs, sz, overflow);
if (overflow) assert(0);

alignmember(alignment, memalignsize, &ofs);
// Skip no-op for noreturn without custom aligment
if (memsize != 0 || alignment != STRUCTALIGN_DEFAULT)
alignmember(alignment, memalignsize, &ofs);

uint memoffset = ofs;
ofs += memsize;
if (ofs > *paggsize)
Expand Down
23 changes: 19 additions & 4 deletions dmd/aliasthis.d
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,32 @@ extern (C++) final class AliasThis : Dsymbol
}
}

Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false)
/*************************************
* Find the `alias this` symbol of e's type.
* Params:
* sc = context
* e = expression forming the `this`
* gag = if true do not print errors, return null instead
* findOnly = don't do further processing like resolving properties,
* i.e. just return plain dotExp() result.
* Returns:
* Expression that is `e.aliasthis`
*/
Expression resolveAliasThis(Scope* sc, Expression e, bool gag = false, bool findOnly = false)
{
import dmd.typesem : dotExp;
for (AggregateDeclaration ad = isAggregate(e.type); ad;)
{
if (ad.aliasthis)
{
uint olderrors = gag ? global.startGagging() : 0;
Loc loc = e.loc;
Type tthis = (e.op == TOK.type ? e.type : null);
e = new DotIdExp(loc, e, ad.aliasthis.ident);
e = e.expressionSemantic(sc);
const flags = DotExpFlag.noAliasThis | (gag ? DotExpFlag.gag : 0);
e = dotExp(e.type, sc, e, ad.aliasthis.ident, flags);
if (!e || findOnly)
return e;

uint olderrors = gag ? global.startGagging() : 0;
if (tthis && ad.aliasthis.sym.needThis())
{
if (e.op == TOK.variable)
Expand Down
19 changes: 16 additions & 3 deletions dmd/argtypes_sysv_x64.d
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ extern (C++) final class ToClassesVisitor : Visitor
t.toBasetype().accept(this);
}

override void visit(TypeNoreturn t)
{
// Treat as void
return visit(Type.tvoid);
}

override void visit(TypeBasic t)
{
switch (t.ty)
Expand Down Expand Up @@ -329,9 +335,6 @@ extern (C++) final class ToClassesVisitor : Visitor

extern(D) void classifyFields(uint baseOffset, size_t nfields, Type delegate(size_t, out uint, out uint) getFieldInfo)
{
if (nfields == 0)
return memory();

// classify each field (recursively for aggregates) and merge all classes per eightbyte
foreach (n; 0 .. nfields)
{
Expand All @@ -348,6 +351,13 @@ extern (C++) final class ToClassesVisitor : Visitor
classifyStructFields(foffset, ts);
else if (auto tsa = ftype.isTypeSArray())
classifyStaticArrayElements(foffset, tsa);
else if (ftype.toBasetype().isTypeNoreturn())
{
// Ignore noreturn members with sizeof = 0
// Potential custom alignment changes are factored in above
nfields--;
continue;
}
else
{
const fEightbyteStart = foffset / 8;
Expand All @@ -373,6 +383,9 @@ extern (C++) final class ToClassesVisitor : Visitor
}
}
}

if (nfields == 0)
return memory();
}

void finalizeAggregate()
Expand Down
9 changes: 7 additions & 2 deletions dmd/attrib.d
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,7 @@ extern (C++) final class AlignDeclaration : AttribDeclaration
super(loc, null, decl);
if (exp)
{
if (!exps)
exps = new Expressions();
exps = new Expressions();
exps.push(exp);
}
}
Expand All @@ -721,6 +720,12 @@ extern (C++) final class AlignDeclaration : AttribDeclaration
this.exps = exps;
}

extern (D) this(const ref Loc loc, structalign_t salign, Dsymbols* decl)
{
super(loc, null, decl);
this.salign = salign;
}

override AlignDeclaration syntaxCopy(Dsymbol s)
{
assert(!s);
Expand Down
27 changes: 27 additions & 0 deletions dmd/cparse.d
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,7 @@ final class CParser(AST) : Parser!AST

auto symbolsSave = symbols;
Specifier specifier;
specifier.packalign = this.packalign;
auto tspec = cparseDeclarationSpecifiers(level, specifier);

/* If a declarator does not follow, it is unnamed
Expand Down Expand Up @@ -2583,6 +2584,11 @@ final class CParser(AST) : Parser!AST

Specifier specifier;
auto tspec = cparseDeclarationSpecifiers(LVL.prototype, specifier);
if (tspec && specifier.mod & MOD.xconst)
{
tspec = toConst(tspec);
specifier.mod = MOD.xnone; // 'used' it
}

Identifier id;
auto t = cparseDeclarator(DTR.xparameter, tspec, id, specifier);
Expand Down Expand Up @@ -2984,6 +2990,15 @@ final class CParser(AST) : Parser!AST
nextToken();
auto mloc = token.loc;

if (token.value == TOK.__attribute__)
{
/* gnu-attributes can appear here, but just scan and ignore them
* https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html
*/
Specifier specifierx;
cparseGnuAttributes(specifierx);
}

AST.Expression value;
if (token.value == TOK.assign)
{
Expand Down Expand Up @@ -3124,6 +3139,7 @@ final class CParser(AST) : Parser!AST

auto symbolsSave = symbols;
Specifier specifier;
specifier.packalign = this.packalign;
auto tspec = cparseSpecifierQualifierList(LVL.member, specifier);

/* If a declarator does not follow, it is unnamed
Expand Down Expand Up @@ -4126,6 +4142,7 @@ final class CParser(AST) : Parser!AST
SCW scw; /// storage-class specifiers
MOD mod; /// type qualifiers
AST.Expressions* alignExps; /// alignment
structalign_t packalign = STRUCTALIGN_DEFAULT; /// #pragma pack alignment value
}

/***********************
Expand Down Expand Up @@ -4292,13 +4309,23 @@ final class CParser(AST) : Parser!AST
*/
private AST.Dsymbol applySpecifier(AST.Dsymbol s, ref Specifier specifier)
{
//printf("applySpecifier() %s\n", s.toChars());
if (specifier.alignExps)
{
//printf(" applying _Alignas %s, packalign %d\n", (*specifier.alignExps)[0].toChars(), cast(int)specifier.packalign);
// Wrap declaration in an AlignDeclaration
auto decls = new AST.Dsymbols(1);
(*decls)[0] = s;
s = new AST.AlignDeclaration(s.loc, specifier.alignExps, decls);
}
else if (specifier.packalign != STRUCTALIGN_DEFAULT)
{
//printf(" applying packalign %d\n", cast(int)specifier.packalign);
// Wrap #pragma pack in an AlignDeclaration
auto decls = new AST.Dsymbols(1);
(*decls)[0] = s;
s = new AST.AlignDeclaration(s.loc, specifier.packalign, decls);
}
return s;
}

Expand Down
18 changes: 17 additions & 1 deletion dmd/dcast.d
Original file line number Diff line number Diff line change
Expand Up @@ -2838,7 +2838,7 @@ Type typeMerge(Scope* sc, TOK op, ref Expression pe1, ref Expression pe2)
return result;
}

/// Converts one of the expression too the other
/// Converts one of the expression to the other
Type convert(ref Expression from, Type to)
{
from = from.castTo(sc, to);
Expand All @@ -2856,6 +2856,22 @@ Type typeMerge(Scope* sc, TOK op, ref Expression pe1, ref Expression pe2)
Type t1b = e1.type.toBasetype();
Type t2b = e2.type.toBasetype();

if (sc && sc.flags & SCOPE.Cfile)
{
// Integral types can be implicitly converted to pointers
if ((t1b.ty == Tpointer) != (t2b.ty == Tpointer))
{
if (t1b.isintegral())
{
return convert(e1, t2b);
}
else if (t2b.isintegral())
{
return convert(e2, t1b);
}
}
}

if (op != TOK.question || t1b.ty != t2b.ty && (t1b.isTypeBasic() && t2b.isTypeBasic()))
{
if (op == TOK.question && t1b.ty.isSomeChar() && t2b.ty.isSomeChar())
Expand Down
1 change: 1 addition & 0 deletions dmd/dclass.d
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import dmd.aggregate;
import dmd.apply;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
import dmd.gluelayer;
import dmd.declaration;
import dmd.dscope;
Expand Down
1 change: 1 addition & 0 deletions dmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import core.stdc.stdio;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
import dmd.ctorflow;
import dmd.dclass;
import dmd.delegatize;
Expand Down
3 changes: 1 addition & 2 deletions dmd/dinterpret.d
Original file line number Diff line number Diff line change
Expand Up @@ -2836,8 +2836,7 @@ version (IN_LLVM)
auto se = ctfeEmplaceExp!StructLiteralExp(e.loc, cast(StructDeclaration)cd, elems, e.newtype);
se.origin = se;
se.ownedByCtfe = OwnedBy.ctfe;
emplaceExp!(ClassReferenceExp)(pue, e.loc, se, e.type);
Expression eref = pue.exp();
Expression eref = ctfeEmplaceExp!ClassReferenceExp(e.loc, se, e.type);
if (e.member)
{
// Call constructor
Expand Down
7 changes: 6 additions & 1 deletion dmd/dscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -735,10 +735,15 @@ version (IN_LLVM)
}
}

/******************************
*/
structalign_t alignment()
{
if (aligndecl)
return aligndecl.getAlignment(&this);
{
auto ad = aligndecl.getAlignment(&this);
return ad.salign;
}
else
return STRUCTALIGN_DEFAULT;
}
Expand Down
1 change: 1 addition & 0 deletions dmd/dstruct.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module dmd.dstruct;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
import dmd.declaration;
import dmd.dmodule;
import dmd.dscope;
Expand Down
12 changes: 11 additions & 1 deletion dmd/dsymbol.d
Original file line number Diff line number Diff line change
Expand Up @@ -2431,7 +2431,7 @@ Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds)


/**********************************************
* ImportC allows redeclarations of variables and functions.
* ImportC allows redeclarations of C variables, functions and typedefs.
* extern int x;
* int x = 3;
* and:
Expand Down Expand Up @@ -2506,5 +2506,15 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy
return fd2;
}

auto td = s.isAliasDeclaration(); // new declaration
auto td2 = s2.isAliasDeclaration(); // existing declaration
if (td && td2)
{
/* BUG: just like with variables and functions, the types should match, which needs semantic() to be run on it.
* FuncDeclaration::semantic2() can detect this, but it relies overnext being set.
*/
return td2;
}

return collision();
}
24 changes: 17 additions & 7 deletions dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,18 @@ else
* ad = AlignmentDeclaration
* sc = context
* Returns:
* alignment as numerical value that is never 0.
* STRUCTALIGN_DEFAULT is used instead.
* STRUCTALIGN_DEFAULT is returned for errors
* ad with alignment value determined
*/
structalign_t getAlignment(AlignDeclaration ad, Scope* sc)
AlignDeclaration getAlignment(AlignDeclaration ad, Scope* sc)
{
if (ad.salign != ad.UNKNOWN) // UNKNOWN is 0
return ad.salign;
return ad;

if (!ad.exps)
return ad.salign = STRUCTALIGN_DEFAULT;
{
ad.salign = STRUCTALIGN_DEFAULT;
return ad;
}

dinteger_t strictest = 0; // strictest alignment
bool errors;
Expand Down Expand Up @@ -163,7 +164,7 @@ structalign_t getAlignment(AlignDeclaration ad, Scope* sc)
ad.salign = (errors || strictest == 0) // C11 6.7.5-6 says alignment of 0 means no effect
? STRUCTALIGN_DEFAULT
: cast(structalign_t) strictest;
return ad.salign;
return ad;
}

const(char)* getMessage(DeprecatedDeclaration dd)
Expand Down Expand Up @@ -945,6 +946,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
sc = sc.push();
sc.stc &= ~(STC.TYPECTOR | STC.pure_ | STC.nothrow_ | STC.nogc | STC.ref_ | STC.disable);

if (sc.flags & SCOPE.Cfile &&
dsym.type.isTypeSArray() &&
dsym.type.isTypeSArray().isIncomplete() &&
dsym._init.isVoidInitializer() &&
!(dsym.storage_class & STC.field))
{
dsym.error("incomplete array type must have initializer");
}

ExpInitializer ei = dsym._init.isExpInitializer();

if (ei) // https://issues.dlang.org/show_bug.cgi?id=13424
Expand Down
2 changes: 1 addition & 1 deletion dmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,7 @@ else
* eg purity(https://issues.dlang.org/show_bug.cgi?id=7295),
* just regard it as not a match.
*/
if (auto e = resolveAliasThis(sc, farg, true))
if (auto e = resolveAliasThis(paramscope, farg, true))
{
farg = e;
goto Lretry;
Expand Down
1 change: 1 addition & 0 deletions dmd/dtoh.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import core.stdc.ctype;

import dmd.astcodegen;
import dmd.arraytypes;
import dmd.attrib;
import dmd.dsymbol;
import dmd.errors;
import dmd.globals;
Expand Down
Loading