diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-28 09:06:06 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-28 09:06:06 +0000 |
commit | 9996a7f06a3c5b4554692e7177930cf4e8ef09af (patch) | |
tree | 3723e42c71d347a7d1314f490440cd25b5f53b6b /lib/AST/Expr.cpp | |
parent | 326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584 (diff) |
Fix the memory leak of FloatingLiteral/IntegerLiteral.
For large floats/integers, APFloat/APInt will allocate memory from the heap to represent these numbers.
Unfortunately, when we use a BumpPtrAllocator to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
the APFloat/APInt values will never get freed.
I introduce the class 'APNumericStorage' which uses ASTContext's allocator for memory allocation and is used internally by FloatingLiteral/IntegerLiteral.
Fixes rdar://7637185
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112361 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index d5cf4d67fc..5feef1c803 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -374,6 +374,44 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { return ""; } +void APNumericStorage::setIntValue(ASTContext &C, const llvm::APInt &Val) { + if (hasAllocation()) + C.Deallocate(pVal); + + BitWidth = Val.getBitWidth(); + unsigned NumWords = Val.getNumWords(); + const uint64_t* Words = Val.getRawData(); + if (NumWords > 1) { + pVal = new (C) uint64_t[NumWords]; + std::copy(Words, Words + NumWords, pVal); + } else if (NumWords == 1) + VAL = Words[0]; + else + VAL = 0; +} + +IntegerLiteral * +IntegerLiteral::Create(ASTContext &C, const llvm::APInt &V, + QualType type, SourceLocation l) { + return new (C) IntegerLiteral(C, V, type, l); +} + +IntegerLiteral * +IntegerLiteral::Create(ASTContext &C, EmptyShell Empty) { + return new (C) IntegerLiteral(Empty); +} + +FloatingLiteral * +FloatingLiteral::Create(ASTContext &C, const llvm::APFloat &V, + bool isexact, QualType Type, SourceLocation L) { + return new (C) FloatingLiteral(C, V, isexact, Type, L); +} + +FloatingLiteral * +FloatingLiteral::Create(ASTContext &C, EmptyShell Empty) { + return new (C) FloatingLiteral(Empty); +} + /// getValueAsApproximateDouble - This returns the value as an inaccurate /// double. Note that this may cause loss of precision, but is useful for /// debugging dumps, etc. |