Revert "[AST] Use APIntStorage to fix memory leak in EnumConstantDecl. (#78311)"

This reverts commit 4737959d91.

Missed an lldb update.
This commit is contained in:
Craig Topper 2024-01-16 12:39:47 -08:00
parent 59a265311a
commit f3d534c425
8 changed files with 63 additions and 100 deletions

View File

@ -675,8 +675,6 @@ Bug Fixes in This Version
Fixes (`#67317 <https://github.com/llvm/llvm-project/issues/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 <https://github.com/llvm/llvm-project/pull/78311>`_)
Before:

View File

@ -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

View File

@ -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 @@ public:
/// 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<EnumConstantDecl>,
public APIntStorage {
class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
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 @@ public:
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;

View File

@ -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 @@ public:
}
};
/// 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;

View File

@ -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());
}

View File

@ -13047,7 +13047,7 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID,
const auto *DR = cast<DeclRefExpr>(CE->getSubExpr());
const auto *Enumerator = cast<EnumConstantDecl>(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());

View File

@ -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() &&

View File

@ -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);
}