diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6c968c628dc14..6e31849ce16dd 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -675,8 +675,6 @@ Bug Fixes in This Version Fixes (`#67317 `_) - Clang now properly diagnoses use of stand-alone OpenMP directives after a label (including ``case`` or ``default`` labels). -- Fix compiler memory leak for enums with underlying type larger than 64 bits. - Fixes (`#78311 `_) Before: diff --git a/clang/include/clang/AST/APNumericStorage.h b/clang/include/clang/AST/APNumericStorage.h deleted file mode 100644 index 95eddbcd86e83..0000000000000 --- a/clang/include/clang/AST/APNumericStorage.h +++ /dev/null @@ -1,71 +0,0 @@ -//===--- APNumericStorage.h - Store APInt/APFloat in ASTContext -*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_AST_APNUMERICSTORAGE_H -#define LLVM_CLANG_AST_APNUMERICSTORAGE_H - -#include "llvm/ADT/APFloat.h" -#include "llvm/ADT/APInt.h" - -namespace clang { -class ASTContext; - -/// Used by IntegerLiteral/FloatingLiteral/EnumConstantDecl to store the -/// numeric without leaking memory. -/// -/// 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. APNumericStorage uses -/// ASTContext's allocator for memory allocation. -class APNumericStorage { - union { - uint64_t VAL; ///< Used to store the <= 64 bits integer value. - uint64_t *pVal; ///< Used to store the >64 bits integer value. - }; - unsigned BitWidth; - - bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } - - APNumericStorage(const APNumericStorage &) = delete; - void operator=(const APNumericStorage &) = delete; - -protected: - APNumericStorage() : VAL(0), BitWidth(0) {} - - llvm::APInt getIntValue() const { - unsigned NumWords = llvm::APInt::getNumWords(BitWidth); - if (NumWords > 1) - return llvm::APInt(BitWidth, NumWords, pVal); - else - return llvm::APInt(BitWidth, VAL); - } - void setIntValue(const ASTContext &C, const llvm::APInt &Val); -}; - -class APIntStorage : private APNumericStorage { -public: - llvm::APInt getValue() const { return getIntValue(); } - void setValue(const ASTContext &C, const llvm::APInt &Val) { - setIntValue(C, Val); - } -}; - -class APFloatStorage : private APNumericStorage { -public: - llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { - return llvm::APFloat(Semantics, getIntValue()); - } - void setValue(const ASTContext &C, const llvm::APFloat &Val) { - setIntValue(C, Val.bitcastToAPInt()); - } -}; - -} // end namespace clang - -#endif // LLVM_CLANG_AST_APNUMERICSTORAGE_H diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 98af552d400f3..a807bcdd76b30 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -13,7 +13,6 @@ #ifndef LLVM_CLANG_AST_DECL_H #define LLVM_CLANG_AST_DECL_H -#include "clang/AST/APNumericStorage.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTContextAllocate.h" #include "clang/AST/DeclAccessPair.h" @@ -3252,16 +3251,15 @@ class FieldDecl : public DeclaratorDecl, public Mergeable { /// that is defined. For example, in "enum X {a,b}", each of a/b are /// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a /// TagType for the X EnumDecl. -class EnumConstantDecl : public ValueDecl, - public Mergeable, - public APIntStorage { +class EnumConstantDecl : public ValueDecl, public Mergeable { Stmt *Init; // an integer constant expression - bool IsUnsigned; + llvm::APSInt Val; // The value. protected: - EnumConstantDecl(const ASTContext &C, DeclContext *DC, SourceLocation L, + EnumConstantDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, - const llvm::APSInt &V); + const llvm::APSInt &V) + : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {} public: friend class StmtIteratorBase; @@ -3274,15 +3272,10 @@ class EnumConstantDecl : public ValueDecl, const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } - llvm::APSInt getInitVal() const { - return llvm::APSInt(getValue(), IsUnsigned); - } + const llvm::APSInt &getInitVal() const { return Val; } void setInitExpr(Expr *E) { Init = (Stmt*) E; } - void setInitVal(const ASTContext &C, const llvm::APSInt &V) { - setValue(C, V); - IsUnsigned = V.isUnsigned(); - } + void setInitVal(const llvm::APSInt &V) { Val = V; } SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 53e4544888ff6..a41f2d66b37b6 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -13,7 +13,6 @@ #ifndef LLVM_CLANG_AST_EXPR_H #define LLVM_CLANG_AST_EXPR_H -#include "clang/AST/APNumericStorage.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTVector.h" #include "clang/AST/ComputeDependence.h" @@ -1480,6 +1479,57 @@ class DeclRefExpr final } }; +/// Used by IntegerLiteral/FloatingLiteral to store the numeric without +/// leaking memory. +/// +/// 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. APNumericStorage uses +/// ASTContext's allocator for memory allocation. +class APNumericStorage { + union { + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t *pVal; ///< Used to store the >64 bits integer value. + }; + unsigned BitWidth; + + bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } + + APNumericStorage(const APNumericStorage &) = delete; + void operator=(const APNumericStorage &) = delete; + +protected: + APNumericStorage() : VAL(0), BitWidth(0) { } + + llvm::APInt getIntValue() const { + unsigned NumWords = llvm::APInt::getNumWords(BitWidth); + if (NumWords > 1) + return llvm::APInt(BitWidth, NumWords, pVal); + else + return llvm::APInt(BitWidth, VAL); + } + void setIntValue(const ASTContext &C, const llvm::APInt &Val); +}; + +class APIntStorage : private APNumericStorage { +public: + llvm::APInt getValue() const { return getIntValue(); } + void setValue(const ASTContext &C, const llvm::APInt &Val) { + setIntValue(C, Val); + } +}; + +class APFloatStorage : private APNumericStorage { +public: + llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const { + return llvm::APFloat(Semantics, getIntValue()); + } + void setValue(const ASTContext &C, const llvm::APFloat &Val) { + setIntValue(C, Val.bitcastToAPInt()); + } +}; + class IntegerLiteral : public Expr, public APIntStorage { SourceLocation Loc; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index d373329d7272a..e1440e5183a4e 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5369,23 +5369,16 @@ void CapturedDecl::setBody(Stmt *B) { BodyAndNothrow.setPointer(B); } bool CapturedDecl::isNothrow() const { return BodyAndNothrow.getInt(); } void CapturedDecl::setNothrow(bool Nothrow) { BodyAndNothrow.setInt(Nothrow); } -EnumConstantDecl::EnumConstantDecl(const ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - QualType T, Expr *E, const llvm::APSInt &V) - : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt *)E) { - setInitVal(C, V); -} - EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V) { - return new (C, CD) EnumConstantDecl(C, CD, L, Id, T, E, V); + return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V); } EnumConstantDecl * EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, + return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ee6866dabaa89..1ed35befe1361 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -13047,7 +13047,7 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID, const auto *DR = cast(CE->getSubExpr()); const auto *Enumerator = cast(DR->getDecl()); - auto InitVal = Enumerator->getInitVal(); + auto &InitVal = Enumerator->getInitVal(); std::string InitValStr; if (InitVal.isNegative() || InitVal > uint64_t(INT64_MAX)) InitValStr = std::to_string(InitVal.getSExtValue()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 793bb90da74d2..722e2ac9e4ff8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20214,7 +20214,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, // Adjust the APSInt value. InitVal = InitVal.extOrTrunc(NewWidth); InitVal.setIsSigned(NewSign); - ECD->setInitVal(Context, InitVal); + ECD->setInitVal(InitVal); // Adjust the Expr initializer and type. if (ECD->getInitExpr() && diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b05efe4f76517..547eb77930b4e 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -910,7 +910,7 @@ void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { VisitValueDecl(ECD); if (Record.readInt()) ECD->setInitExpr(Record.readExpr()); - ECD->setInitVal(Reader.getContext(), Record.readAPSInt()); + ECD->setInitVal(Record.readAPSInt()); mergeMergeable(ECD); }