From 11619e55a9346b86fb2868fe6cc67e5a472c2546 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 14 Oct 2012 03:33:42 +0200 Subject: [PATCH] Fix miscompilation of some functions returning structs. --- gen/functions.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/gen/functions.cpp b/gen/functions.cpp index 79334f2c..f52d7d43 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -69,11 +69,25 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, if (abi->returnInArg(f)) { #if LDC_LLVM_VER >= 302 - fty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attributes::get(llvm::Attributes::Builder().addAttribute(llvm::Attributes::StructRet) - .addAttribute(llvm::Attributes::NoAlias) - .addAttribute(llvm::Attributes::NoCapture))); + fty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attributes::get( + llvm::Attributes::Builder().addAttribute(llvm::Attributes::StructRet) + .addAttribute(llvm::Attributes::NoAlias) + #if !STRUCTTHISREF + // In D2 where 'this' in structs is a reference, nocapture + // might not actually be applicable, even if it probably still + // is for all sane code from a high-level semantic standpoint. + // Specifying nocapture on a parameter but then passing it as a + // non-nocapture argument in a function call can lead to + // _silent_ miscompilations (especially in the GVN pass). + .addAttribute(llvm::Attributes::NoCapture) + #endif + )); #else - fty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias | NoCapture); + fty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias + #if !STRUCTTHISREF + | NoCapture + #endif + ); #endif rt = Type::tvoid; lidx++;