From 6f236518b513cecb703370d9a8cbe2536dc8a982 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Tue, 19 Jun 2012 22:35:12 +0200 Subject: [PATCH] =?UTF-8?q?Fixes=20#123=20=E2=80=93=20Linking=20of=20pre/p?= =?UTF-8?q?ost-condition=20in=20interface=20fails=20when=20interface=20imp?= =?UTF-8?q?lemented=20in=20separate=20module.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gen/tollvm.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 2eadbc1c..7223cd87 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -5,6 +5,7 @@ #include "aggregate.h" #include "declaration.h" #include "init.h" +#include "id.h" #include "module.h" #include "gen/tollvm.h" @@ -310,11 +311,18 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) assert(0 && "not global/function"); } - // The following breaks for nested naked functions and other declarations, so check for that. + // The following breaks for nested naked functions and the implicitly + // generated __require/__ensure functions for in/out contracts. The reason + // for the latter is that contract functions, despite being nested, can be + // referenced from other D modules e.g. in the case of contracts on + // interface methods (where __require/__ensure are emitted to the module + // where the interface is declared, but an actual interface implementation + // can be in a completely different place). bool skipNestedCheck = !mustDefineSymbol(sym); if (!skipNestedCheck) if (FuncDeclaration* fd = sym->isFuncDeclaration()) - skipNestedCheck = (fd->naked != 0); + skipNestedCheck = (fd->naked != 0) || + (fd->ident == Id::require) || (fd->ident == Id::ensure); // Any symbol nested in a function that cannot be inlined can't be // referenced directly from outside that function, so we can give