[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays=<n> for stricter handling of flexible arrays
Stephan Bergmann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 27 22:58:38 PDT 2022
sberg added a comment.
In D126864#3612149 <https://reviews.llvm.org/D126864#3612149>, @sberg wrote:
> see https://reviews.llvm.org/D128643 "[clang] -fsanitize=array-bounds: treat all trailing size-1 arrays as flexible" for another regression
For the record (now that the original commit has been reverted anyway for now):
Besides the above regression for `-fsanitize=array-bounds` and macro'ized array size in HarfBuzz, I also ran into yet another regression when Firebird is built with `-fsanitize=array-bounds`: That project, in https://github.com/FirebirdSQL/firebird/blob/master/src/lock/lock_proto.h uses a trailing member
srq lhb_hash[1]; // Hash table
as a flexible array, but declared in a
struct lhb : public Firebird::MemoryHeader
that is not a standard-layout class (because the `Firebird::MemoryHeader` base class also declares non-static data members). And `isFlexibleArrayMember` returns `false` if the surrounding class is not a standard-layout class.
In the end, what brought back a successful `-fsanitize=array-bounds` LibreOffice (which bundles those HarfBuzz and Firebird, among others) for me was to exclude the whole set of blocks
// Don't consider sizes resulting from macro expansions or template argument
// substitution to form C89 tail-padded arrays.
TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
while (TInfo) {
TypeLoc TL = TInfo->getTypeLoc();
// Look through typedefs.
if (TypedefTypeLoc TTL = TL.getAs<TypedefTypeLoc>()) {
const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
TInfo = TDL->getTypeSourceInfo();
continue;
}
if (ConstantArrayTypeLoc CTL = TL.getAs<ConstantArrayTypeLoc>()) {
const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr());
if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
return false;
}
break;
}
const ObjCInterfaceDecl *ID =
dyn_cast<ObjCInterfaceDecl>(FD->getDeclContext());
const RecordDecl *RD = dyn_cast<RecordDecl>(FD->getDeclContext());
if (RD) {
if (RD->isUnion())
return false;
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
if (!CRD->isStandardLayout())
return false;
}
} else if (!ID)
return false;
(by means of an additional `bool` parameter) when `isFlexibleArrayMember` is called from `getArrayIndexingBound` (in `clang/lib/CodeGen/CGExpr.cpp`).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D126864/new/
https://reviews.llvm.org/D126864
More information about the cfe-commits
mailing list