@@ -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,27 +964,26 @@ 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 ) {
969+ irLocal->value = getNullPtr ();
970+ return ;
971+ }
972+
973+ llvm::AllocaInst *allocainst;
974+
975+ if (type != vd->type ) {
915976 allocainst = DtoAlloca (type, vd->toChars ());
916- isRealAlloca = true ;
917977 } else {
918978 allocainst = DtoAlloca (vd, vd->toChars ());
919- isRealAlloca = true ;
920979 }
921980
922981 irLocal->value = allocainst;
923982
924- if (!lltype->isVoidTy ())
925- gIR ->DBuilder .EmitLocalVariable (allocainst, vd);
983+ gIR ->DBuilder .EmitLocalVariable (allocainst, vd);
926984
927- // Lifetime annotation is only valid on alloca.
928- if (isRealAlloca) {
929- // The lifetime of a stack variable starts from the point it is declared
985+ // The lifetime of a stack variable starts from the point it is declared
986+ if (!vd->isParameter () && !varIsSret (vd, gIR ->func ())) {
930987 gIR ->funcGen ().localVariableLifetimeAnnotator .addLocalVariable (
931988 allocainst, DtoConstUlong (size (type)));
932989 }
0 commit comments