@@ -169,7 +169,6 @@ struct ModuleGroup
169169
170170 enum OnCycle
171171 {
172- deprecate,
173172 abort,
174173 print,
175174 ignore
@@ -180,7 +179,9 @@ struct ModuleGroup
180179 switch (cycleHandling) with (OnCycle)
181180 {
182181 case " deprecate" :
183- onCycle = deprecate;
182+ import core.stdc.stdio : fprintf, stderr;
183+ // Option deprecated in 2.101, remove in 2.111
184+ fprintf(stderr, " `--DRT-oncycle=deprecate` is no longer supported, using `abort` instead\n " );
184185 break ;
185186 case " abort" :
186187 onCycle = abort;
@@ -356,14 +357,6 @@ struct ModuleGroup
356357 // was already started, this is a cycle.
357358 final switch (onCycle) with (OnCycle)
358359 {
359- case deprecate:
360- // check with old algorithm
361- if (sortCtorsOld(edges))
362- {
363- // unwind to print deprecation message.
364- return false ; // deprecated cycle error
365- }
366- goto case abort; // fall through
367360 case abort:
368361
369362 string errmsg = " " ;
@@ -533,193 +526,6 @@ struct ModuleGroup
533526 sortCtors(rt_configOption(" oncycle" ));
534527 }
535528
536- /* *****************************
537- * This is the old ctor sorting algorithm that does not find all cycles.
538- *
539- * It is here to allow the deprecated behavior from the original algorithm
540- * until people have fixed their code.
541- *
542- * If no cycles are found, the _ctors and _tlsctors are replaced with the
543- * ones generated by this algorithm to preserve the old incorrect ordering
544- * behavior.
545- *
546- * Params:
547- * edges = The module edges as found in the `importedModules` member of
548- * each ModuleInfo. Generated in sortCtors.
549- * Returns:
550- * true if no cycle is found, false if one was.
551- */
552- bool sortCtorsOld (int [][] edges)
553- {
554- immutable len = edges.length;
555- assert (len == _modules.length);
556-
557- static struct StackRec
558- {
559- @property int mod()
560- {
561- return _mods[_idx];
562- }
563-
564- int [] _mods;
565- size_t _idx;
566- }
567-
568- auto stack = (cast (StackRec* ).calloc(len, StackRec.sizeof))[0 .. len];
569- // TODO: reuse GCBits by moving it to core.internal.container
570- immutable nwords = (len + 8 * size_t .sizeof - 1 ) / (8 * size_t .sizeof);
571- auto ctorstart = cast (size_t * ).malloc(nwords * size_t .sizeof);
572- auto ctordone = cast (size_t * ).malloc(nwords * size_t .sizeof);
573- int [] initialEdges = (cast (int * )malloc(int .sizeof * len))[0 .. len];
574- if (! stack.ptr || ctorstart is null || ctordone is null || ! initialEdges.ptr)
575- assert (0 );
576- scope (exit)
577- {
578- .free(stack.ptr);
579- .free(ctorstart);
580- .free(ctordone);
581- .free(initialEdges.ptr);
582- }
583-
584- // initialize the initial edges
585- foreach (i, ref v; initialEdges)
586- v = cast (int )i;
587-
588- bool sort (ref immutable (ModuleInfo )* [] ctors, uint mask)
589- {
590- import core.bitop ;
591-
592- ctors = (cast (immutable (ModuleInfo )** ).malloc(len * size_t .sizeof))[0 .. len];
593- if (! ctors.ptr)
594- assert (0 );
595-
596- // clean flags
597- memset(ctorstart, 0 , nwords * size_t .sizeof);
598- memset(ctordone, 0 , nwords * size_t .sizeof);
599- size_t stackidx = 0 ;
600- size_t cidx;
601-
602- int [] mods = initialEdges;
603-
604- size_t idx;
605- while (true )
606- {
607- while (idx < mods.length)
608- {
609- auto m = mods[idx];
610-
611- if (bt(ctordone, m))
612- {
613- // this module has already been processed, skip
614- ++ idx;
615- continue ;
616- }
617- else if (bt(ctorstart, m))
618- {
619- /* Trace back to the begin of the cycle.
620- */
621- bool ctorInCycle;
622- size_t start = stackidx;
623- while (start-- )
624- {
625- auto sm = stack[start].mod;
626- if (sm == m)
627- break ;
628- assert (sm >= 0 );
629- if (bt(ctorstart, sm))
630- ctorInCycle = true ;
631- }
632- assert (stack[start].mod == m);
633- if (ctorInCycle)
634- {
635- return false ;
636- }
637- else
638- {
639- /* This is also a cycle, but the import chain does not constrain
640- * the order of initialization, either because the imported
641- * modules have no ctors or the ctors are standalone.
642- */
643- ++ idx;
644- }
645- }
646- else
647- {
648- auto curmod = _modules[m];
649- if (curmod.flags & mask)
650- {
651- if (curmod.flags & MIstandalone || ! edges[m].length)
652- { // trivial ctor => sort in
653- ctors[cidx++ ] = curmod;
654- bts(ctordone, m);
655- }
656- else
657- { // non-trivial ctor => defer
658- bts(ctorstart, m);
659- }
660- }
661- else // no ctor => mark as visited
662- {
663- bts(ctordone, m);
664- }
665-
666- if (edges[m].length)
667- {
668- /* Internal runtime error, recursion exceeds number of modules.
669- */
670- (stackidx < len) || assert (0 );
671-
672- // recurse
673- stack[stackidx++ ] = StackRec(mods, idx);
674- idx = 0 ;
675- mods = edges[m];
676- }
677- }
678- }
679-
680- if (stackidx)
681- { // pop old value from stack
682- -- stackidx;
683- mods = stack[stackidx]._mods;
684- idx = stack[stackidx]._idx;
685- auto m = mods[idx++ ];
686- if (bt(ctorstart, m) && ! bts(ctordone, m))
687- ctors[cidx++ ] = _modules[m];
688- }
689- else // done
690- break ;
691- }
692- // store final number and shrink array
693- ctors = (cast (immutable (ModuleInfo )** ).realloc(ctors.ptr, cidx * size_t .sizeof))[0 .. cidx];
694- return true ;
695- }
696-
697- /* Do two passes: ctor/dtor, tlsctor/tlsdtor
698- */
699- immutable (ModuleInfo )* [] _ctors2;
700- immutable (ModuleInfo )* [] _tlsctors2;
701- auto result = sort(_ctors2, MIctor | MIdtor) && sort(_tlsctors2, MItlsctor | MItlsdtor);
702- if (result) // no cycle
703- {
704- // fall back to original ordering as part of the deprecation.
705- if (_ctors.ptr)
706- .free(_ctors.ptr);
707- _ctors = _ctors2;
708- if (_tlsctors.ptr)
709- .free(_tlsctors.ptr);
710- _tlsctors = _tlsctors2;
711- }
712- else
713- {
714- // free any allocated memory that will be forgotten
715- if (_ctors2.ptr)
716- .free(_ctors2.ptr);
717- if (_tlsctors2.ptr)
718- .free(_tlsctors2.ptr);
719- }
720- return result;
721- }
722-
723529 void runCtors ()
724530 {
725531 // run independent ctors
0 commit comments