@@ -858,6 +858,64 @@ void DtoResolveVariable(VarDeclaration *vd) {
858858 }
859859}
860860
861+ namespace {
862+ bool eval (VarDeclaration *vd, Expression *e) {
863+
864+ auto ve = e->isVarExp ();
865+ if (!ve) {
866+ return false ;
867+ }
868+ VarDeclaration *v = nullptr ;
869+ if (ve)
870+ v = ve->var ->isVarDeclaration ();
871+ return vd == v;
872+ }
873+ bool walk (VarDeclaration *vd, CommaExp *ce) {
874+ IF_LOG Logger::println (" ce = %s" , ce->toChars ());
875+ if (auto ce2 = ce->e2 ->isCommaExp ()) {
876+ if (walk (vd, ce2))
877+ return true ;
878+ }
879+ if (auto ce1 = ce->e1 ->isCommaExp ()) {
880+ if (walk (vd, ce1))
881+ return true ;
882+ }
883+ if (eval (vd, ce->e2 ))
884+ return true ;
885+ if (eval (vd, ce->e1 ))
886+ return true ;
887+ return false ;
888+ }
889+ bool varIsSret (VarDeclaration *vd, IrFunction *f) {
890+ if (!f->sretArg )
891+ return false ;
892+ auto fd = f->decl ;
893+ auto rets = fd->returns ;
894+ if (!rets)
895+ return false ;
896+ #if LDC_LLVM_VER >= 1800
897+ #define startswith starts_with
898+ #endif
899+ llvm::StringRef name = vd->ident ->toChars ();
900+ if (name.startswith (" __tmpfordtor" ) ||name.startswith (" __sl" )) {
901+ return true ;
902+ }
903+ #if LDC_LLVM_VER >= 1800
904+ #undef startswith
905+ #endif
906+ for (d_size_t i = 0 ; i < rets->length ; i++) {
907+ auto rs = (*rets)[i];
908+ Expression *e = rs->exp ;
909+ CommaExp *ce = e->isCommaExp ();
910+ if (ce) {
911+ if (walk (vd, ce)) return true ;
912+ }
913+ if (eval (vd, e))
914+ return true ;
915+ }
916+ return false ;
917+ }
918+ }
861919/* *****************************************************************************
862920 * DECLARATION EXP HELPER
863921 ******************************************************************************/
@@ -906,29 +964,22 @@ void DtoVarDeclaration(VarDeclaration *vd) {
906964
907965 // We also allocate a variable for zero-sized variables, because they are technically not `null` when loaded.
908966 // The x86_64 ABI "loads" zero-sized function arguments, and without an allocation ASan will report an error (Github #4816).
909- llvm::Value *allocainst;
910- bool isRealAlloca = false ;
911967 LLType *lltype = DtoType (type); // void for noreturn
912968 if (lltype->isVoidTy ()) {
913- allocainst = getNullPtr ();
914- } else if (type != vd->type ) {
915- allocainst = DtoAlloca (type, vd->toChars ());
916- isRealAlloca = true ;
917- } else {
918- allocainst = DtoAlloca (vd, vd->toChars ());
919- isRealAlloca = true ;
969+ irLocal->value = getNullPtr ();
920970 }
921-
922- irLocal->value = allocainst;
923-
924- if (!lltype->isVoidTy ())
971+ else {
972+ auto allocainst = type != vd->type ? DtoAlloca (type, vd->toChars ())
973+ : DtoAlloca (vd, vd->toChars ());
974+ irLocal->value = allocainst;
975+
925976 gIR ->DBuilder .EmitLocalVariable (allocainst, vd);
926-
927- // Lifetime annotation is only valid on alloca.
928- if (isRealAlloca) {
977+
929978 // The lifetime of a stack variable starts from the point it is declared
930- gIR ->funcGen ().localVariableLifetimeAnnotator .addLocalVariable (
931- allocainst, DtoConstUlong (size (type)));
979+ if (!vd->isParameter () && !varIsSret (vd, gIR ->func ())) {
980+ gIR ->funcGen ().localVariableLifetimeAnnotator .addLocalVariable (
981+ allocainst, DtoConstUlong (size (type)));
982+ }
932983 }
933984 }
934985
0 commit comments