Skip to content

Commit

Permalink
fix issue 18456 - crt_constructor/crt_destructor segfaults if -lib
Browse files Browse the repository at this point in the history
delay objmod.setModuleCtorDtor until the function is actually generated
don't make them extra object files in a library, they will never be linked
  • Loading branch information
rainers committed Dec 24, 2018
1 parent faca601 commit 20afb43
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/dmd/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,8 @@ class FuncDeclaration : public Declaration
bool naked; // true if naked
bool generated; // true if function was generated by the compiler rather than
// supplied by the user
unsigned char isCrtCtorDtor; // has attribute pragma(crt_constructor(1)/crt_destructor(2))
// not set before the glue layer
ILS inlineStatusStmt;
ILS inlineStatusExp;
PINLINE inlining;
Expand Down
3 changes: 3 additions & 0 deletions src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ extern (C++) class FuncDeclaration : Declaration
bool naked; /// true if naked
bool generated; /// true if function was generated by the compiler rather than
/// supplied by the user
ubyte isCrtCtorDtor; /// has attribute pragma(crt_constructor(1)/crt_destructor(2))
/// not set before the glue layer

ILS inlineStatusStmt = ILS.uninitialized;
ILS inlineStatusExp = ILS.uninitialized;
PINLINE inlining = PINLINE.default_;
Expand Down
7 changes: 6 additions & 1 deletion src/dmd/glue.d
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
if (ud && !global.params.useUnitTests)
return;

if (multiobj && !fd.isStaticDtorDeclaration() && !fd.isStaticCtorDeclaration())
if (multiobj && !fd.isStaticDtorDeclaration() && !fd.isStaticCtorDeclaration() && !fd.isCrtCtorDtor)
{
obj_append(fd);
return;
Expand Down Expand Up @@ -1244,6 +1244,11 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
if (fd.isExport())
objmod.export_symbol(s, cast(uint)Para.offset);

if (fd.isCrtCtorDtor & 1)
objmod.setModuleCtorDtor(s, true);
if (fd.isCrtCtorDtor & 2)
objmod.setModuleCtorDtor(s, false);

foreach (sd; *irs.deferToObj)
{
toObjFile(sd, false);
Expand Down
9 changes: 4 additions & 5 deletions src/dmd/toobj.d
Original file line number Diff line number Diff line change
Expand Up @@ -784,10 +784,7 @@ void toObjFile(Dsymbol ds, bool multiobj)

obj_linkerdirective(directive);
}

visit(cast(AttribDeclaration)pd);

if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
{
immutable isCtor = pd.ident == Id.crt_constructor;

Expand All @@ -806,7 +803,7 @@ void toObjFile(Dsymbol ds, bool multiobj)
}
else if (auto f = s.isFuncDeclaration())
{
objmod.setModuleCtorDtor(s.csym, isCtor);
f.isCrtCtorDtor |= isCtor ? 1 : 2;
if (f.linkage != LINK.c)
f.error("must be `extern(C)` for `pragma(%s)`", isCtor ? "crt_constructor".ptr : "crt_destructor".ptr);
return 1;
Expand All @@ -819,6 +816,8 @@ void toObjFile(Dsymbol ds, bool multiobj)
if (recurse(pd, isCtor) > 1)
pd.error("can only apply to a single declaration");
}

visit(cast(AttribDeclaration)pd);
}

override void visit(TemplateInstance ti)
Expand Down
8 changes: 8 additions & 0 deletions test/runnable/extra-files/lib18456.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

__gshared int initVar;

pragma(crt_constructor)
extern(C) void mir_cpuid_crt_init()
{
initVar = 42;
}
6 changes: 6 additions & 0 deletions test/runnable/extra-files/test18456.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import lib18456;

void main()
{
assert(initVar == 42);
}
7 changes: 7 additions & 0 deletions test/runnable/test18456.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${LIBEXT} -lib ${EXTRA_FILES}/lib18456.d
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${EXE} ${EXTRA_FILES}/test18456.d ${OUTPUT_BASE}${LIBEXT}
${OUTPUT_BASE}${EXE}

rm ${OUTPUT_BASE}{${LIBEXT},${EXE}}

0 comments on commit 20afb43

Please sign in to comment.