Skip to content

Commit 849e5ea

Browse files
authored
[clang][bytecode] Add Descriptor::getDataType() (llvm#132681)
This returns the type of data in the Block, which might be different than the type of the expression or declaration we created the block for. This lets us remove some special cases from CheckNewDeleteForms() and CheckNewTypeMismatch().
1 parent 38d71c9 commit 849e5ea

File tree

4 files changed

+30
-20
lines changed

4 files changed

+30
-20
lines changed

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "PrimType.h"
1717
#include "Record.h"
1818
#include "Source.h"
19+
#include "clang/AST/ExprCXX.h"
1920

2021
using namespace clang;
2122
using namespace clang::interp;
@@ -453,6 +454,30 @@ QualType Descriptor::getElemQualType() const {
453454
return T;
454455
}
455456

457+
QualType Descriptor::getDataType(const ASTContext &Ctx) const {
458+
auto MakeArrayType = [&](QualType ElemType) -> QualType {
459+
if (IsArray)
460+
return Ctx.getConstantArrayType(
461+
ElemType, APInt(64, static_cast<uint64_t>(getNumElems()), false),
462+
nullptr, ArraySizeModifier::Normal, 0);
463+
return ElemType;
464+
};
465+
466+
if (const auto *E = asExpr()) {
467+
if (isa<CXXNewExpr>(E))
468+
return MakeArrayType(E->getType()->getPointeeType());
469+
470+
// std::allocator.allocate() call.
471+
if (const auto *ME = dyn_cast<CXXMemberCallExpr>(E);
472+
ME && ME->getRecordDecl()->getName() == "allocator" &&
473+
ME->getMethodDecl()->getName() == "allocate")
474+
return MakeArrayType(E->getType()->getPointeeType());
475+
return E->getType();
476+
}
477+
478+
return getType();
479+
}
480+
456481
SourceLocation Descriptor::getLocation() const {
457482
if (auto *D = dyn_cast<const Decl *>(Source))
458483
return D->getLocation();

clang/lib/AST/ByteCode/Descriptor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ struct Descriptor final {
207207

208208
QualType getType() const;
209209
QualType getElemQualType() const;
210+
QualType getDataType(const ASTContext &Ctx) const;
210211
SourceLocation getLocation() const;
211212
SourceInfo getLoc() const;
212213

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -979,17 +979,7 @@ bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC,
979979
if (AllocForm == DeleteForm)
980980
return true;
981981

982-
QualType TypeToDiagnose;
983-
// We need to shuffle things around a bit here to get a better diagnostic,
984-
// because the expression we allocated the block for was of type int*,
985-
// but we want to get the array size right.
986-
if (D->isArray()) {
987-
QualType ElemQT = D->getType()->getPointeeType();
988-
TypeToDiagnose = S.getASTContext().getConstantArrayType(
989-
ElemQT, APInt(64, static_cast<uint64_t>(D->getNumElems()), false),
990-
nullptr, ArraySizeModifier::Normal, 0);
991-
} else
992-
TypeToDiagnose = D->getType()->getPointeeType();
982+
QualType TypeToDiagnose = D->getDataType(S.getASTContext());
993983

994984
const SourceInfo &E = S.Current->getSource(OpPC);
995985
S.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
@@ -1665,15 +1655,7 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
16651655
return false;
16661656

16671657
const auto *NewExpr = cast<CXXNewExpr>(E);
1668-
QualType StorageType = Ptr.getType();
1669-
1670-
if ((isa_and_nonnull<CXXNewExpr>(Ptr.getFieldDesc()->asExpr()) ||
1671-
isa_and_nonnull<CXXMemberCallExpr>(Ptr.getFieldDesc()->asExpr())) &&
1672-
StorageType->isPointerType()) {
1673-
// FIXME: Are there other cases where this is a problem?
1674-
StorageType = StorageType->getPointeeType();
1675-
}
1676-
1658+
QualType StorageType = Ptr.getFieldDesc()->getDataType(S.getASTContext());
16771659
const ASTContext &ASTCtx = S.getASTContext();
16781660
QualType AllocType;
16791661
if (ArraySize) {

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ static QualType getElemType(const Pointer &P) {
158158
return T->getAs<PointerType>()->getPointeeType();
159159
if (Desc->isArray())
160160
return Desc->getElemQualType();
161+
if (const auto *AT = T->getAsArrayTypeUnsafe())
162+
return AT->getElementType();
161163
return T;
162164
}
163165

0 commit comments

Comments
 (0)