diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-12-05 17:11:12 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-12-09 00:58:58 +0100 |
commit | 0fb57034770aa20adced4d176f34ca611c2945bf (patch) | |
tree | 1f5735c8b4f25aa4a290e5ae8124713c24f98359 /gcc/d/dmd/func.d | |
parent | c15aa46cca0649b68613d3292cf71c7cc57ef78f (diff) | |
download | gcc-0fb57034770aa20adced4d176f34ca611c2945bf.zip gcc-0fb57034770aa20adced4d176f34ca611c2945bf.tar.gz gcc-0fb57034770aa20adced4d176f34ca611c2945bf.tar.bz2 |
d: Merge upstream dmd 568496d5b, druntime 178c44ff, phobos 574bf883b.
D front-end changes:
- Import dmd v2.098.0
- New ImportC module for compiling preprocessed C11 code into D.
- New -ftransition=in switch.
- Improved handling of new 'noreturn' type.
Druntime changes:
- Import druntime v2.098.0
- Fix broken import in core.sys.linux.perf_event module (PR103558).
Phobos changes:
- Import phobos v2.098.0
- All sources are now compiled with -fpreview=fieldwise.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 568496d5b.
* Make-lang.in (D_FRONTEND_OBJS): Add d/common-file.o,
d/common-outbuffer.o, d/common-string.o, d/file_manager.o,
d/importc.o. Remove d/root-outbuffer.o.
(d/common-%.o): New recipe.
* d-builtins.cc (build_frontend_type): Update for new front-end
interface.
(d_build_d_type_nodes): Set noreturn_type_node.
* d-codegen.cc (d_build_call): Don't call function if one of the
arguments is type 'noreturn'.
(build_vthis_function): Propagate TYPE_QUAL_VOLATILE from original
function type.
* d-frontend.cc (eval_builtin): Update signature.
(getTypeInfoType): Likewise.
(toObjFile): New function.
* d-gimplify.cc (d_gimplify_call_expr): Always evaluate arguments from
left to right.
* d-lang.cc (d_handle_option): Handle OPT_ftransition_in.
(d_parse_file): Don't generate D main if it is declared in user code.
* d-tree.h (CALL_EXPR_ARGS_ORDERED): Remove.
(enum d_tree_index): Add DTI_BOTTOM_TYPE.
(noreturn_type_node): New.
* decl.cc (apply_pragma_crt): Remove.
(DeclVisitor::visit): Update for new front-end interface.
(DeclVisitor::visit (PragmaDeclaration *)): Don't handle
crt_constructor and crt_destructor pragmas.
(DeclVisitor::visit (VarDeclaration *)): Don't generate declarations
of type 'noreturn'.
(DeclVisitor::visit (FuncDeclaration *)): Stop adding parameters when
'noreturn' type has been encountered.
(get_symbol_decl): Set DECL_STATIC_CONSTRUCTOR and
DECL_STATIC_DESTRUCTOR on decl node if requested.
(aggregate_initializer_decl): Update for new front-end interface.
* expr.cc (ExprVisitor::visit (CallExp *)): Always use the 'this'
object as the result of calling any constructor function.
(ExprVisitor::visit): Update for new front-end interface.
* gdc.texi (Runtime Options): Document -fmain and -ftransition=in.
* lang.opt (ftransition=in): New option.
* modules.cc (get_internal_fn): Update for new front-end interface.
* types.cc (TypeVisitor::visit): Likewise.
(TypeVisitor::visit (TypeNoreturn *)): Return noreturn_type_node.
(TypeVisitor::visit (TypeFunction *)): Stop adding parameters when
'notreturn' type has been encountered. Qualify function types that
return 'noreturn' as TYPE_QUAL_VOLATILE.
libphobos/ChangeLog:
PR d/103558
* libdruntime/MERGE: Merge upstream druntime 178c44ff.
* libdruntime/Makefile.am (DRUNTIME_DSOURCES_LINUX): Add
core/sys/linux/syscalls.d.
(DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/pthread_np.d.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos 574bf883b.
* src/Makefile.am (D_EXTRA_DFLAGS): Add -fpreview=fieldwise.
* src/Makefile.in: Regenerate.
* testsuite/libphobos.exceptions/assert_fail.d: Update test.
* testsuite/libphobos.betterc/test22336.d: New test.
Diffstat (limited to 'gcc/d/dmd/func.d')
-rw-r--r-- | gcc/d/dmd/func.d | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 7f0b0bb..2d6a756 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -45,7 +45,8 @@ import dmd.identifier; import dmd.init; import dmd.mtype; import dmd.objc; -import dmd.root.outbuffer; +import dmd.root.aav; +import dmd.common.outbuffer; import dmd.root.rootobject; import dmd.root.string; import dmd.root.stringtable; @@ -261,6 +262,8 @@ extern (C++) class FuncDeclaration : Declaration VarDeclaration vresult; /// result variable for out contracts LabelDsymbol returnLabel; /// where the return goes + bool[size_t] isTypeIsolatedCache; /// cache for the potentially very expensive isTypeIsolated check + // used to prevent symbols in different // scopes from having the same name DsymbolTable localsymtab; @@ -740,7 +743,7 @@ extern (C++) class FuncDeclaration : Declaration */ final BaseClass* overrideInterface() { - if (ClassDeclaration cd = toParent2().isClassDeclaration()) + for (ClassDeclaration cd = toParent2().isClassDeclaration(); cd; cd = cd.baseClass) { foreach (b; cd.interfaces) { @@ -1529,8 +1532,23 @@ extern (C++) class FuncDeclaration : Declaration extern (D) final bool isTypeIsolated(Type t) { StringTable!Type parentTypes; - parentTypes._init(); - return isTypeIsolated(t, parentTypes); + const uniqueTypeID = t.getUniqueID(); + if (uniqueTypeID) + { + const cacheResultPtr = uniqueTypeID in isTypeIsolatedCache; + if (cacheResultPtr !is null) + return *cacheResultPtr; + + parentTypes._init(); + const isIsolated = isTypeIsolated(t, parentTypes); + isTypeIsolatedCache[uniqueTypeID] = isIsolated; + return isIsolated; + } + else + { + parentTypes._init(); + return isTypeIsolated(t, parentTypes); + } } ///ditto @@ -2593,9 +2611,10 @@ extern (C++) class FuncDeclaration : Declaration } if (!tf.nextOf()) - error("must return `int` or `void`"); - else if (tf.nextOf().ty != Tint32 && tf.nextOf().ty != Tvoid) - error("must return `int` or `void`, not `%s`", tf.nextOf().toChars()); + // auto main(), check after semantic + assert(this.inferRetType); + else if (tf.nextOf().ty != Tint32 && tf.nextOf().ty != Tvoid && tf.nextOf().ty != Tnoreturn) + error("must return `int`, `void` or `noreturn`, not `%s`", tf.nextOf().toChars()); else if (tf.parameterList.varargs || nparams >= 2 || argerr) error("parameters must be `main()` or `main(string[] args)`"); } @@ -3054,7 +3073,11 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, return null; bool hasOverloads = fd.overnext !is null; - auto tf = fd.type.toTypeFunction(); + auto tf = fd.type.isTypeFunction(); + // if type is an error, the original type should be there for better diagnostics + if (!tf) + tf = fd.originalType.toTypeFunction(); + if (tthis && !MODimplicitConv(tthis.mod, tf.mod)) // modifier mismatch { OutBuffer thisBuf, funcBuf; @@ -3253,17 +3276,7 @@ private bool traverseIndirections(Type ta, Type tb) { //printf("traverseIndirections(%s, %s)\n", ta.toChars(), tb.toChars()); - /* Threaded list of aggregate types already examined, - * used to break cycles. - * Cycles in type graphs can only occur with aggregates. - */ - static struct Ctxt - { - Ctxt* prev; - Type type; // an aggregate type - } - - static bool traverse(Type ta, Type tb, Ctxt* ctxt, bool reversePass) + static bool traverse(Type ta, Type tb, ref scope AssocArray!(const(char)*, bool) table, bool reversePass) { //printf("traverse(%s, %s)\n", ta.toChars(), tb.toChars()); ta = ta.baseElemOf(); @@ -3293,28 +3306,27 @@ private bool traverseIndirections(Type ta, Type tb) if (tb.ty == Tclass || tb.ty == Tstruct) { - for (Ctxt* c = ctxt; c; c = c.prev) - if (tb == c.type) - return true; - Ctxt c; - c.prev = ctxt; - c.type = tb; - /* Traverse the type of each field of the aggregate */ + bool* found = table.getLvalue(tb.deco); + if (*found == true) + return true; // We have already seen this symbol, break the cycle + else + *found = true; + AggregateDeclaration sym = tb.toDsymbol(null).isAggregateDeclaration(); foreach (v; sym.fields) { Type tprmi = v.type.addMod(tb.mod); //printf("\ttb = %s, tprmi = %s\n", tb.toChars(), tprmi.toChars()); - if (!traverse(ta, tprmi, &c, reversePass)) + if (!traverse(ta, tprmi, table, reversePass)) return false; } } else if (tb.ty == Tarray || tb.ty == Taarray || tb.ty == Tpointer) { Type tind = tb.nextOf(); - if (!traverse(ta, tind, ctxt, reversePass)) + if (!traverse(ta, tind, table, reversePass)) return false; } else if (tb.hasPointers()) @@ -3325,7 +3337,10 @@ private bool traverseIndirections(Type ta, Type tb) // Still no match, so try breaking up ta if we have not done so yet. if (!reversePass) - return traverse(tb, ta, ctxt, true); + { + scope newTable = AssocArray!(const(char)*, bool)(); + return traverse(tb, ta, newTable, true); + } return true; } @@ -3333,7 +3348,8 @@ private bool traverseIndirections(Type ta, Type tb) // To handle arbitrary levels of indirections in both parameters, we // recursively descend into aggregate members/levels of indirection in both // `ta` and `tb` while avoiding cycles. Start with the original types. - const result = traverse(ta, tb, null, false); + scope table = AssocArray!(const(char)*, bool)(); + const result = traverse(ta, tb, table, false); //printf(" returns %d\n", result); return result; } |