Fix more alloc-dealloc mismatches and use-after-scopes (#55420)
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Mon, 12 Jul 2021 22:55:26 +0000 (15:55 -0700)
committerGitHub <noreply@github.com>
Mon, 12 Jul 2021 22:55:26 +0000 (22:55 +0000)
* Fix another dynamically-sized allocation to use new/delete instead of the mismatched new[]/delete.

* Fix use-after-scope

* Fix another alloc-dealloc mismatch

* Update src/coreclr/vm/threadstatics.cpp

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* Use standard size_t instead of custom SIZE_T typedef.

* Fix formatting.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
src/coreclr/jit/lsrabuild.cpp
src/coreclr/vm/threadstatics.cpp
src/coreclr/vm/threadstatics.h

index f5f4d781d759ec0ba22bd0efb07a705a3c289fe7..da7cb15b7cd08ad8e60ae36f047b70587e453ce3 100644 (file)
@@ -3559,6 +3559,7 @@ int LinearScan::BuildReturn(GenTree* tree)
                 noway_assert(op1->IsMultiRegCall() || op1->IsMultiRegLclVar());
 
                 int                   srcCount;
+                ReturnTypeDesc        nonCallRetTypeDesc;
                 const ReturnTypeDesc* pRetTypeDesc;
                 if (op1->OperIs(GT_CALL))
                 {
@@ -3567,13 +3568,12 @@ int LinearScan::BuildReturn(GenTree* tree)
                 else
                 {
                     assert(compiler->lvaEnregMultiRegVars);
-                    LclVarDsc*     varDsc = compiler->lvaGetDesc(op1->AsLclVar()->GetLclNum());
-                    ReturnTypeDesc retTypeDesc;
-                    retTypeDesc.InitializeStructReturnType(compiler, varDsc->GetStructHnd(),
-                                                           compiler->info.compCallConv);
-                    pRetTypeDesc = &retTypeDesc;
+                    LclVarDsc* varDsc = compiler->lvaGetDesc(op1->AsLclVar()->GetLclNum());
+                    nonCallRetTypeDesc.InitializeStructReturnType(compiler, varDsc->GetStructHnd(),
+                                                                  compiler->info.compCallConv);
+                    pRetTypeDesc = &nonCallRetTypeDesc;
                     assert(compiler->lvaGetDesc(op1->AsLclVar()->GetLclNum())->lvFieldCnt ==
-                           retTypeDesc.GetReturnRegCount());
+                           nonCallRetTypeDesc.GetReturnRegCount());
                 }
                 srcCount = pRetTypeDesc->GetReturnRegCount();
                 // For any source that's coming from a different register file, we need to ensure that
index 2644d7ad5fc91a67035eeaae019c907e5362e4b4..bac0f082fb8eda2c4f107c9ebf755cee7e9927e1 100644 (file)
@@ -97,7 +97,7 @@ void ThreadLocalBlock::FreeTable()
         SpinLock::Holder lock(&m_TLMTableLock);
 
         // Free the table itself
-        delete m_pTLMTable;
+        delete[] m_pTLMTable;
         m_pTLMTable = NULL;
     }
 
@@ -136,7 +136,7 @@ void ThreadLocalBlock::EnsureModuleIndex(ModuleIndex index)
 
     // If this allocation fails, we will throw. If it succeeds,
     // then we are good to go
-    PTR_TLMTableEntry pNewModuleSlots = (PTR_TLMTableEntry) (void*) new BYTE[sizeof(TLMTableEntry) * aModuleIndices];
+    PTR_TLMTableEntry pNewModuleSlots = new TLMTableEntry[aModuleIndices];
 
     // Zero out the new TLM table
     memset(pNewModuleSlots, 0 , sizeof(TLMTableEntry) * aModuleIndices);
@@ -704,9 +704,7 @@ PTR_ThreadLocalModule ThreadStatics::AllocateTLM(Module * pModule)
 
     SIZE_T size = pModule->GetThreadLocalModuleSize();
 
-    _ASSERTE(size >= ThreadLocalModule::OffsetOfDataBlob());
-
-    PTR_ThreadLocalModule pThreadLocalModule = (ThreadLocalModule*)new BYTE[size];
+    PTR_ThreadLocalModule pThreadLocalModule = new({ pModule }) ThreadLocalModule;
 
     // We guarantee alignment for 64-bit regular thread statics on 32-bit platforms even without FEATURE_64BIT_ALIGNMENT for performance reasons.
 
index 1755bf7230d20f03aeed6928e3ecab025066f1bb..ddb59b5cbc20d638c3783912249bd3979c770e58 100644 (file)
@@ -450,6 +450,20 @@ public:
         return GetPrecomputedStaticsClassData()[classID] & ClassInitFlags::INITIALIZED_FLAG;
     }
 
+    void* operator new(size_t) = delete;
+
+    struct ParentModule { PTR_Module pModule; };
+
+    void* operator new(size_t baseSize, ParentModule parentModule)
+    {
+        size_t size = parentModule.pModule->GetThreadLocalModuleSize();
+
+        _ASSERTE(size >= baseSize);
+        _ASSERTE(size >= ThreadLocalModule::OffsetOfDataBlob());
+
+        return ::operator new(size);
+    }
+
 #ifndef DACCESS_COMPILE
 
     FORCEINLINE void EnsureClassAllocated(MethodTable * pMT)