[llvm] f4dd1bc - [AMDGPU] Fix leak and self-assignment in copy assignment operator (#107847)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 11 02:23:45 PDT 2024
Author: Fraser Cormack
Date: 2024-09-11T10:23:41+01:00
New Revision: f4dd1bc8fc625d3938f95b9d06aaaeebd2e90dca
URL: https://github.com/llvm/llvm-project/commit/f4dd1bc8fc625d3938f95b9d06aaaeebd2e90dca
DIFF: https://github.com/llvm/llvm-project/commit/f4dd1bc8fc625d3938f95b9d06aaaeebd2e90dca.diff
LOG: [AMDGPU] Fix leak and self-assignment in copy assignment operator (#107847)
A static analyzer identified that this operator was unsafe in the case
of self-assignment.
In the placement new statement, StringValue's copy constructor was being
implicitly called, which received a reference to "itself". In fact, it
was being passed an old StringValue at the same address - one whose
lifetime had already ended. The copy constructor was thus copying fields
from a dead object.
We need to be careful when switching active union members, and calling
the destructor on the old StringValue will avoid memory leaks which I
believe the old code exhibited.
Added:
Modified:
llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index 7af5e7388f841e..4cc60f50978996 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -100,19 +100,25 @@ struct SIArgument {
SIArgument() : IsRegister(false), StackOffset(0) {}
SIArgument(const SIArgument &Other) {
IsRegister = Other.IsRegister;
- if (IsRegister) {
- ::new ((void *)std::addressof(RegisterName))
- StringValue(Other.RegisterName);
- } else
+ if (IsRegister)
+ new (&RegisterName) StringValue(Other.RegisterName);
+ else
StackOffset = Other.StackOffset;
Mask = Other.Mask;
}
SIArgument &operator=(const SIArgument &Other) {
+ // Default-construct or destruct the old RegisterName in case of switching
+ // union members
+ if (IsRegister != Other.IsRegister) {
+ if (Other.IsRegister)
+ new (&RegisterName) StringValue();
+ else
+ RegisterName.~StringValue();
+ }
IsRegister = Other.IsRegister;
- if (IsRegister) {
- ::new ((void *)std::addressof(RegisterName))
- StringValue(Other.RegisterName);
- } else
+ if (IsRegister)
+ RegisterName = Other.RegisterName;
+ else
StackOffset = Other.StackOffset;
Mask = Other.Mask;
return *this;
More information about the llvm-commits
mailing list