gentoo / dlang

[MIRROR] D programming language ebuild repository
https://gitweb.gentoo.org/repo/user/dlang.git
GNU General Public License v2.0
30 stars 25 forks source link

>dmd-2.097 removal of 2_083 from DLANG_VERSION_RANGE #115

Closed the-horo closed 8 months ago

the-horo commented 1 year ago

2_083 has been removed as a valid DLANG_VERSION for dmd-2.097 and onward. This is done because there is a build failure:

Run: /usr/lib/dmd/2.083/bin/dmd -of/var/tmp/portage/dev-lang/dmd-2.097.2/work/dmd2/dmd/generated/linux/release/64/dmd -vtls -J/var/tmp/portage/dev-lang/dmd-2.097.2/work/dmd2/dmd/src/dmd/res -version=MARS -w -de -fPIC -m64 -J/var/tmp/portage/dev-lang/dmd-2.097.2/work/dmd2/dmd/generated/linux/release/64 -I/var/tmp/portage/dev-lang/dmd-2.097.2/work/dmd2/dmd/src -dip25 -O -inline -release -color=on src/dmd/dinifile.d src/dmd/gluelayer.d src/dmd/lib.d src/dmd/libelf.d src/dmd/libmach.d src/dmd/libmscoff.d src/dmd/libomf.d src/dmd/link.d src/dmd/mars.d src/dmd/scanelf.d src/dmd/scanmach.d src/dmd/scanmscoff.d src/dmd/scanomf.d src/dmd/vsoptions.d src/dmd/access.d src/dmd/aggregate.d src/dmd/aliasthis.d src/dmd/apply.d src/dmd/argtypes_x86.d src/dmd/argtypes_sysv_x64.d src/dmd/argtypes_aarch64.d src/dmd/arrayop.d src/dmd/arraytypes.d src/dmd/ast_node.d src/dmd/astcodegen.d src/dmd/asttypename.d src/dmd/attrib.d src/dmd/blockexit.d src/dmd/builtin.d src/dmd/canthrow.d src/dmd/chkformat.d src/dmd/cli.d src/dmd/clone.d src/dmd/compiler.d src/dmd/complex.d src/dmd/cond.d src/dmd/constfold.d src/dmd/cppmangle.d src/dmd/cppmanglewin.d src/dmd/ctfeexpr.d src/dmd/ctorflow.d src/dmd/dcast.d src/dmd/dclass.d src/dmd/declaration.d src/dmd/delegatize.d src/dmd/denum.d src/dmd/dimport.d src/dmd/dinterpret.d src/dmd/dmacro.d src/dmd/dmangle.d src/dmd/dmodule.d src/dmd/doc.d src/dmd/dscope.d src/dmd/dstruct.d src/dmd/dsymbol.d src/dmd/dsymbolsem.d src/dmd/dtemplate.d src/dmd/dtoh.d src/dmd/dversion.d src/dmd/env.d src/dmd/escape.d src/dmd/expression.d src/dmd/expressionsem.d src/dmd/func.d src/dmd/hdrgen.d src/dmd/impcnvtab.d src/dmd/imphint.d src/dmd/init.d src/dmd/initsem.d src/dmd/inline.d src/dmd/inlinecost.d src/dmd/intrange.d src/dmd/json.d src/dmd/lambdacomp.d src/dmd/mtype.d src/dmd/nogc.d src/dmd/nspace.d src/dmd/ob.d src/dmd/objc.d src/dmd/opover.d src/dmd/optimize.d src/dmd/parse.d src/dmd/parsetimevisitor.d src/dmd/permissivevisitor.d src/dmd/printast.d src/dmd/safe.d src/dmd/sapply.d src/dmd/semantic2.d src/dmd/semantic3.d src/dmd/sideeffect.d src/dmd/statement.d src/dmd/statement_rewrite_walker.d src/dmd/statementsem.d src/dmd/staticassert.d src/dmd/staticcond.d src/dmd/stmtstate.d src/dmd/target.d src/dmd/templateparamsem.d src/dmd/traits.d src/dmd/transitivevisitor.d src/dmd/typesem.d src/dmd/typinf.d src/dmd/utils.d src/dmd/visitor.d src/dmd/foreachvar.d src/dmd/dmsc.d src/dmd/e2ir.d src/dmd/eh.d src/dmd/iasm.d src/dmd/iasmdmd.d src/dmd/iasmgcc.d src/dmd/glue.d src/dmd/objc_glue.d src/dmd/s2ir.d src/dmd/tocsym.d src/dmd/toctype.d src/dmd/tocvdebug.d src/dmd/todt.d src/dmd/toir.d src/dmd/toobj.d src/dmd/backend/cc.d src/dmd/backend/cdef.d src/dmd/backend/cgcv.d src/dmd/backend/code.d src/dmd/backend/cv4.d src/dmd/backend/dt.d src/dmd/backend/el.d src/dmd/backend/global.d src/dmd/backend/obj.d src/dmd/backend/oper.d src/dmd/backend/outbuf.d src/dmd/backend/rtlsym.d src/dmd/backend/code_x86.d src/dmd/backend/iasm.d src/dmd/backend/codebuilder.d src/dmd/backend/ty.d src/dmd/backend/type.d src/dmd/backend/exh.d src/dmd/backend/mach.d src/dmd/backend/mscoff.d src/dmd/backend/dwarf.d src/dmd/backend/dwarf2.d src/dmd/backend/xmm.d src/dmd/backend/dlist.d src/dmd/backend/melf.d src/dmd/root/aav.d src/dmd/root/longdouble.d src/dmd/root/man.d src/dmd/root/response.d src/dmd/root/speller.d src/dmd/root/string.d src/dmd/root/strtold.d generated/linux/release/64/lexer.o generated/linux/release/64/backend.o
src/dmd/target.d(122):        called from here: `defaultTargetOS()`
src/dmd/dtoh.d(428): `warned` is thread local

This error, however, is not very helpful, as it does not say anything about any error, just giving some context. The src/dmd/dtoh.d line is only an information message enabled by -vtls.

As the output of the command looks incomplete, it may be useful to run the command directly, instead of through portage. The output in a terminal of this command is:

src/dmd/target.d(122):        called from here: defaultTargetOS()
src/dmd/dtoh.d(428): `warned` is thread local
Illegal instruction

Yikes, Illegal instruction, not the best thing to see. So, we have stumbled into an ICE bug. Let's start with the only information we know, src/dmd/target.d(122).

  Target.OS defaultTargetOS()
  {
      version (Windows)
      return Target.OS.Windows;
      else version (linux)
      return Target.OS.linux;
      else version (OSX)
      return Target.OS.OSX;
      else version (FreeBSD)
      return Target.OS.FreeBSD;
      else version (OpenBSD)
      return Target.OS.OpenBSD;
      else version (Solaris)
      return Target.OS.Solaris;
      else version (DragonFlyBSD)
      return Target.OS.DragonFlyBSD;
      else
      static assert(0, "unknown TARGET");
  }

  extern (C++) struct Target
  {
      /// Bit decoding of the Target.OS
      enum OS : ubyte
      {
      /* These are mutually exclusive; one and only one is set.
       ,* Match spelling and casing of corresponding version identifiers
       ,*/
      Freestanding = 0,
      linux        = 1,
      Windows      = 2,
      OSX          = 4,
      OpenBSD      = 8,
      FreeBSD      = 0x10,
      Solaris      = 0x20,
      DragonFlyBSD = 0x40,

      // Combination masks
      all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
      Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
      }

      OS os = defaultTargetOS(); // (this is the line)

We have a struct Target that has a member os. Since D structs must have a compile time known default constructor, it means that defaultTargetOS() needs to be executed at compile time. The function is defined above, a glorified compile time if statement, that returns a Target.OS type. This is probably where the error resides, the compiler ran into a cycle of Target needing defaultTargetOS needing Target. To make sure let's start by making changes to the code.

We start small, only changing the defaultTargetOS's body to:

  Target.OS defaultTargetOS()
  {
      return Target.OS.linux;
  }

No, same error. Let's try to get rid of the type:

  ubyte defaultTargetOS()
  {
      return 1;
  }

  // ...
      OS os = cast(Target.OS)defaultTargetOS(); // (this is the line)

Now we get an erorr in another place, but this time it's an actual error:

src/dmd/mars.d(265): Error: cannot implicitly convert expression defaultTargetOS() of type ubyte to OS

This is something we can work it. Obviously, by changing the function, other places in the code now fail, needing the cast(Target.OS). Changing mars.d, which is the only other file referencing the function, we are finally able to build >dmd-2.097.

There is another way to achieve this result, since the error happens when calling the function at compile time, we can just not call it:

      OS os = OS.linux; // (this is the line)

This would accomplish the same thing, allbeit without platform compatibility, by changing a single line, more managable then 1 function and 2 files.

Although the same code appears in ldc2, its compilation succeds, for reasons I can't argue.

I am not asking for a change to be made (i.e. a new patch to be added), I just wanted to write down the reasons why that removal has been made, and possible fixes, for an easy future reference. The commit which introduced the breaking change is https://github.com/dlang/dmd/commit/f4bfbd7e008c05645b68af85a749ad13d593480b

the-horo commented 8 months ago

dmd:2.083 is no longer packaged in the overlay so the dmd-2_083 USE flag is no longer available.