Skip to content

[Clang] Generate the GEP instead of adding AST nodes #73730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3e500c2
[Clang] Generate the GEP instead of adding AST nodes
bwendling Nov 29, 2023
47d6daf
Reformat.
bwendling Nov 29, 2023
54199ea
Remove Swedish Chef references and use the correct type in the for-ea…
bwendling Nov 29, 2023
b915f62
Check that we have a real counted_by expression.
bwendling Nov 29, 2023
d19cc51
Use the correct indices for the fields. Also generate an 'inbounds' G…
bwendling Nov 29, 2023
279ca2e
Reformat
bwendling Nov 29, 2023
71b05ee
Add support for compound literals.
bwendling Nov 29, 2023
d2a3e9e
When finding the base of the expression, stop when we reach an Expr t…
bwendling Nov 29, 2023
5c95289
Reformat
bwendling Nov 29, 2023
a6e71d8
Avoid any side-effects.
bwendling Dec 5, 2023
81ecab0
Add testcases for pointer arithmetic.
bwendling Dec 5, 2023
aa5c417
Add comment for ExprLValueMap.
bwendling Dec 5, 2023
9f50d41
Reformat
bwendling Dec 5, 2023
f96e5a3
Find the correct field number when bitfields are present.
bwendling Dec 6, 2023
d7ab6e7
Reformat
bwendling Dec 6, 2023
200aabe
Remove ExprLValueMap in favor of generating the bounds check in EmitA…
bwendling Dec 6, 2023
55d961d
Reformat
bwendling Dec 6, 2023
424fe03
Use unfortunately too similarly named arguments into the correct plac…
bwendling Dec 6, 2023
fe6d40c
Update
bwendling Dec 6, 2023
81be48a
Disabmiguate the new EmitBoundsCheck function. And use a consistent s…
bwendling Dec 7, 2023
31aa93c
Disambiguate method name. Add a 'VisitStmt' function returning nullpt…
bwendling Dec 8, 2023
6ae3bb5
Reformat
bwendling Dec 8, 2023
a9aa39b
Use correct version of EmitCountedByField
bwendling Dec 8, 2023
2567c46
Merge branch 'llvm:main' into counted-by-fix-with-gep-pr73168
bwendling Dec 8, 2023
b5cf2a9
Add informational comment.
bwendling Dec 8, 2023
dbde66c
Merge branch 'llvm:main' into counted-by-fix-with-gep-pr73168
bwendling Dec 11, 2023
8d470eb
Don't re-emit the pointer. Instead look through the GEPs for the base…
bwendling Dec 12, 2023
e30ca7e
Clarify name.
bwendling Dec 12, 2023
5b0f233
Update testcase.
bwendling Dec 12, 2023
19dfa6d
Once we find the GEP with the struct base type value, we don't have t…
bwendling Dec 14, 2023
3266e26
Add testcase for a complicated base pointer.
bwendling Dec 14, 2023
941ca31
Emit a pointer for __bdos calculations if hasn't already been emitted…
bwendling Dec 15, 2023
5682028
Calculate the 'count' using an offset from the flexible array member.…
bwendling Dec 16, 2023
213a88f
There can be a nullptr Scope?
bwendling Dec 18, 2023
e6d9ac4
Reformat
bwendling Dec 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -6436,6 +6436,8 @@ def err_flexible_array_counted_by_attr_field_not_integer : Error<
"field %0 in 'counted_by' must be a non-boolean integer type">;
def note_flexible_array_counted_by_attr_field : Note<
"field %0 declared here">;
def err_flexible_array_counted_by_in_substructure : Error<
"'counted_by' applied to flexible array in substructure">;

let CategoryName = "ARC Semantic Issue" in {

Expand Down
39 changes: 16 additions & 23 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,31 +876,26 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
}

// Get the flexible array member Decl.
const ValueDecl *FAMDecl = nullptr;
const RecordDecl *OuterRD = nullptr;
if (const auto *ME = dyn_cast<MemberExpr>(Base)) {
// Check if \p Base is referencing the FAM itself.
if (const ValueDecl *MD = ME->getMemberDecl()) {
const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
if (!Decl::isFlexibleArrayMemberLike(
Ctx, MD, MD->getType(), StrictFlexArraysLevel,
/*IgnoreTemplateOrMacroSubstitution=*/true))
return nullptr;

FAMDecl = MD;
}
const ValueDecl *VD = ME->getMemberDecl();
OuterRD = VD->getDeclContext()->getOuterLexicalRecordContext();
} else if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
// Check if we're pointing to the whole struct.
QualType Ty = DRE->getDecl()->getType();
if (Ty->isPointerType())
Ty = Ty->getPointeeType();

if (const auto *RD = Ty->getAsRecordDecl())
// Don't use the outer lexical record because the FAM might be in a
// different RecordDecl.
FAMDecl = FindFlexibleArrayMemberField(Ctx, RD);
OuterRD = Ty->getAsRecordDecl();
}

if (!OuterRD)
return nullptr;

uint64_t Offset = 0;
const ValueDecl *FAMDecl = FindFlexibleArrayMemberField(Ctx, OuterRD, Offset);
Offset = Ctx.toCharUnitsFromBits(Offset).getQuantity();

if (!FAMDecl || !FAMDecl->hasAttr<CountedByAttr>())
// No flexible array member found or it doesn't have the "counted_by"
// attribute.
Expand All @@ -913,8 +908,10 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,

// Build a load of the counted_by field.
bool IsSigned = CountedByFD->getType()->isSignedIntegerType();
const Expr *CountedByExpr = BuildCountedByFieldExpr(Base, CountedByFD);
Value *CountedByInst = EmitAnyExprToTemp(CountedByExpr).getScalarVal();
Value *CountedByInst = EmitCountedByFieldExpr(Base, CountedByFD);
if (!CountedByInst)
return nullptr;

llvm::Type *CountedByTy = CountedByInst->getType();

// Build a load of the index and subtract it from the count.
Expand Down Expand Up @@ -944,14 +941,10 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,

if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
// The whole struct is specificed in the __bdos.
const RecordDecl *OuterRD =
CountedByFD->getDeclContext()->getOuterLexicalRecordContext();
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(OuterRD);

// Get the offset of the FAM.
CharUnits Offset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FAMDecl));
llvm::Constant *FAMOffset =
ConstantInt::get(ResType, Offset.getQuantity(), IsSigned);
llvm::Constant *FAMOffset = ConstantInt::get(ResType, Offset, IsSigned);
Value *OffsetAndFAMSize =
Builder.CreateAdd(FAMOffset, Res, "", !IsSigned, IsSigned);

Expand Down
Loading