[clang] Revert "[Clang] Implement the 'counted_by' attribute" (PR #68603)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 9 08:55:43 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
<details>
<summary>Changes</summary>
This reverts commit 9a954c693573281407f6ee3f4eb1b16cc545033d, which causes clang
crashes when compiling with `-fsanitize=bounds`. See
https://github.com/llvm/llvm-project/commit/9a954c693573281407f6ee3f4eb1b16cc545033d#commitcomment-129529574
for details.
---
Patch is 48.64 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/68603.diff
18 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (-5)
- (modified) clang/include/clang/AST/Decl.h (-24)
- (modified) clang/include/clang/AST/DeclBase.h (-10)
- (modified) clang/include/clang/Basic/Attr.td (-18)
- (modified) clang/include/clang/Basic/AttrDocs.td (-66)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (-15)
- (modified) clang/include/clang/Sema/Sema.h (-2)
- (modified) clang/lib/AST/ASTImporter.cpp (-13)
- (modified) clang/lib/AST/DeclBase.cpp (+1-75)
- (modified) clang/lib/AST/Expr.cpp (+73-10)
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (-51)
- (modified) clang/lib/CodeGen/CGExpr.cpp (+3-61)
- (modified) clang/lib/CodeGen/CodeGenFunction.h (-6)
- (modified) clang/lib/Sema/SemaDecl.cpp (-12)
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (-132)
- (removed) clang/test/CodeGen/attr-counted-by.c (-227)
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (-1)
- (removed) clang/test/Sema/attr-counted-by.c (-42)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 078d697d8465242..d85db6f795c5274 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -139,11 +139,6 @@ C Language Changes
- ``structs``, ``unions``, and ``arrays`` that are const may now be used as
constant expressions. This change is more consistent with the behavior of
GCC.
-- Clang now supports the C-only attribute ``counted_by``. When applied to a
- struct's flexible array member, it points to the struct field that holds the
- number of elements in the flexible array member. This information can improve
- the results of the array bound sanitizer and the
- ``__builtin_dynamic_object_size`` builtin.
C23 Feature Support
^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7f076cc77ea82cb..02e30e24c8be470 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4302,30 +4302,6 @@ class RecordDecl : public TagDecl {
return field_begin() == field_end();
}
- FieldDecl *getLastField() {
- FieldDecl *FD = nullptr;
- for (FieldDecl *Field : fields())
- FD = Field;
- return FD;
- }
- const FieldDecl *getLastField() const {
- return const_cast<RecordDecl *>(this)->getLastField();
- }
-
- template <typename Functor>
- const FieldDecl *findFieldIf(Functor &Pred) const {
- for (const Decl *D : decls()) {
- if (const auto *FD = dyn_cast<FieldDecl>(D); FD && Pred(FD))
- return FD;
-
- if (const auto *RD = dyn_cast<RecordDecl>(D))
- if (const FieldDecl *FD = RD->findFieldIf(Pred))
- return FD;
- }
-
- return nullptr;
- }
-
/// Note that the definition of this type is now complete.
virtual void completeDefinition();
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index d383e46e22e16f4..12137387b676a7d 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -18,7 +18,6 @@
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
@@ -478,15 +477,6 @@ class alignas(8) Decl {
// Return true if this is a FileContext Decl.
bool isFileContextDecl() const;
- /// Whether it resembles a flexible array member. This is a static member
- /// because we want to be able to call it with a nullptr. That allows us to
- /// perform non-Decl specific checks based on the object's type and strict
- /// flex array level.
- static bool isFlexibleArrayMemberLike(
- ASTContext &Context, const Decl *D, QualType Ty,
- LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
- bool IgnoreTemplateOrMacroSubstitution);
-
ASTContext &getASTContext() const LLVM_READONLY;
/// Helper to get the language options from the ASTContext.
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 5c9eb7b8a981037..7a6ec77ae84b15a 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4246,21 +4246,3 @@ def AvailableOnlyInDefaultEvalMethod : InheritableAttr {
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Documentation = [Undocumented];
}
-
-def CountedBy : InheritableAttr {
- let Spellings = [Clang<"counted_by">];
- let Subjects = SubjectList<[Field]>;
- let Args = [IdentifierArgument<"CountedByField">];
- let Documentation = [CountedByDocs];
- let LangOpts = [COnly];
- // FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl
- // isn't yet available due to the fact that we're still parsing the
- // structure. Maybe that code could be changed sometime in the future.
- code AdditionalMembers = [{
- private:
- SourceRange CountedByFieldLoc;
- public:
- SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; }
- void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; }
- }];
-}
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 9f9991bdae36155..8d928dcc146b254 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7275,69 +7275,3 @@ relative ordering of values is important. For example:
attribute, they default to the value ``65535``.
}];
}
-
-def CountedByDocs : Documentation {
- let Category = DocCatField;
- let Content = [{
-Clang supports the ``counted_by`` attribute on the flexible array member of a
-structure in C. The argument for the attribute is the name of a field member in
-the same structure holding the count of elements in the flexible array. This
-information can be used to improve the results of the array bound sanitizer and
-the ``__builtin_dynamic_object_size`` builtin.
-
-For example, the following code:
-
-.. code-block:: c
-
- struct bar;
-
- struct foo {
- size_t count;
- char other;
- struct bar *array[] __attribute__((counted_by(count)));
- };
-
-specifies that the flexible array member ``array`` has the number of elements
-allocated for it stored in ``count``. This establishes a relationship between
-``array`` and ``count``. Specifically, ``p->array`` must have at least
-``p->count`` number of elements available. It's the user's responsibility to
-ensure that this relationship is maintained through changes to the structure.
-
-In the following example, the allocated array erroneously has fewer elements
-than what's specified by ``p->count``. This would result in an out-of-bounds
-access not being detected.
-
-.. code-block:: c
-
- #define SIZE_INCR 42
-
- struct foo *p;
-
- void foo_alloc(size_t count) {
- p = malloc(MAX(sizeof(struct foo),
- offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
- p->count = count + SIZE_INCR;
- }
-
-The next example updates ``p->count``, breaking the relationship requirement
-that ``p->array`` must have at least ``p->count`` number of elements available:
-
-.. code-block:: c
-
- #define SIZE_INCR 42
-
- struct foo *p;
-
- void foo_alloc(size_t count) {
- p = malloc(MAX(sizeof(struct foo),
- offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
- p->count = count;
- }
-
- void use_foo(int index) {
- p->count += SIZE_INCR + 1; /* 'count' is now larger than the number of elements of 'array'. */
- p->array[index] = 0; /* the sanitizer can't properly check if this is an out-of-bounds access. */
- }
-
- }];
-}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b211680a0e9b6e9..c1a6e3831127e56 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6389,21 +6389,6 @@ def warn_superclass_variable_sized_type_not_at_end : Warning<
"field %0 can overwrite instance variable %1 with variable sized type %2"
" in superclass %3">, InGroup<ObjCFlexibleArray>;
-def err_counted_by_attr_not_on_flexible_array_member : Error<
- "'counted_by' only applies to flexible array members">;
-def err_flexible_array_counted_by_attr_field_not_found : Error<
- "field %0 in 'counted_by' not found">;
-def err_flexible_array_counted_by_attr_field_not_found_suggest : Error<
- "field %0 in 'counted_by' not found; did you mean %1?">;
-def err_flexible_array_counted_by_attr_field_not_found_in_struct : Error<
- "field %0 in 'counted_by' is not found in struct">;
-def err_flexible_array_counted_by_attr_refers_to_self : Error<
- "field %0 in 'counted_by' cannot refer to the flexible array">;
-def err_flexible_array_counted_by_attr_field_not_integer : Error<
- "field %0 in 'counted_by' is not a non-boolean integer type">;
-def note_flexible_array_counted_by_attr_field : Note<
- "field %0 declared here">;
-
let CategoryName = "ARC Semantic Issue" in {
// ARC-mode diagnostics.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1c88855a73970d3..2ebd21090ae4e11 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4795,8 +4795,6 @@ class Sema final {
bool CheckAlwaysInlineAttr(const Stmt *OrigSt, const Stmt *CurSt,
const AttributeCommonInfo &A);
- bool CheckCountedByAttr(Scope *Scope, const FieldDecl *FD);
-
/// Adjust the calling convention of a method to be the ABI default if it
/// wasn't specified explicitly. This handles method types formed from
/// function type typedefs and typename template arguments.
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3adbabdb7fb878a..72e70427161bb0e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -8978,10 +8978,6 @@ class AttrImporter {
public:
AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {}
- // Useful for accessing the imported attribute.
- template <typename T> T *castAttrAs() { return cast<T>(ToAttr); }
- template <typename T> const T *castAttrAs() const { return cast<T>(ToAttr); }
-
// Create an "importer" for an attribute parameter.
// Result of the 'value()' of that object is to be passed to the function
// 'importAttr', in the order that is expected by the attribute class.
@@ -9188,15 +9184,6 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
From->args_size());
break;
}
- case attr::CountedBy: {
- AI.cloneAttr(FromAttr);
- const auto *CBA = cast<CountedByAttr>(FromAttr);
- Expected<SourceRange> SR = Import(CBA->getCountedByFieldLoc()).get();
- if (!SR)
- return SR.takeError();
- AI.castAttrAs<CountedByAttr>()->setCountedByFieldLoc(SR.get());
- break;
- }
default: {
// The default branch works for attributes that have no arguments to import.
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 4823d70aa7e4954..3804f1a5b49d3cd 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -29,6 +29,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/PartialDiagnostic.h"
@@ -410,81 +411,6 @@ bool Decl::isFileContextDecl() const {
return DC && DC->isFileContext();
}
-bool Decl::isFlexibleArrayMemberLike(
- ASTContext &Ctx, const Decl *D, QualType Ty,
- LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
- bool IgnoreTemplateOrMacroSubstitution) {
- // For compatibility with existing code, we treat arrays of length 0 or
- // 1 as flexible array members.
- const auto *CAT = Ctx.getAsConstantArrayType(Ty);
- if (CAT) {
- using FAMKind = LangOptions::StrictFlexArraysLevelKind;
-
- llvm::APInt Size = CAT->getSize();
- FAMKind StrictFlexArraysLevel =
- Ctx.getLangOpts().getStrictFlexArraysLevel();
-
- if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
- return false;
-
- // GCC extension, only allowed to represent a FAM.
- if (Size.isZero())
- return true;
-
- if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
- return false;
-
- if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
- return false;
- } else if (!Ctx.getAsIncompleteArrayType(Ty)) {
- return false;
- }
-
- if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D))
- return OID->getNextIvar() == nullptr;
-
- const auto *FD = dyn_cast_if_present<FieldDecl>(D);
- if (!FD)
- return false;
-
- if (CAT) {
- // GCC treats an array memeber of a union as an FAM if the size is one or
- // zero.
- llvm::APInt Size = CAT->getSize();
- if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
- return true;
- }
-
- // Don't consider sizes resulting from macro expansions or template argument
- // substitution to form C89 tail-padded arrays.
- if (IgnoreTemplateOrMacroSubstitution) {
- TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
- while (TInfo) {
- TypeLoc TL = TInfo->getTypeLoc();
-
- // Look through typedefs.
- if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
- const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
- TInfo = TDL->getTypeSourceInfo();
- continue;
- }
-
- if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) {
- const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr());
- if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
- return false;
- }
-
- break;
- }
- }
-
- // Test that the field is the last in the structure.
- RecordDecl::field_iterator FI(
- DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
- return ++FI == FD->getParent()->field_end();
-}
-
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
return TUD;
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 5d3b510df1ef9b3..4bfc4f082cd6a69 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -205,22 +205,85 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
}
bool Expr::isFlexibleArrayMemberLike(
- ASTContext &Ctx,
+ ASTContext &Context,
LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
bool IgnoreTemplateOrMacroSubstitution) const {
+
+ // For compatibility with existing code, we treat arrays of length 0 or
+ // 1 as flexible array members.
+ const auto *CAT = Context.getAsConstantArrayType(getType());
+ if (CAT) {
+ llvm::APInt Size = CAT->getSize();
+
+ using FAMKind = LangOptions::StrictFlexArraysLevelKind;
+
+ if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
+ return false;
+
+ // GCC extension, only allowed to represent a FAM.
+ if (Size == 0)
+ return true;
+
+ if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
+ return false;
+
+ if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
+ return false;
+ } else if (!Context.getAsIncompleteArrayType(getType()))
+ return false;
+
const Expr *E = IgnoreParens();
- const Decl *D = nullptr;
- if (const auto *ME = dyn_cast<MemberExpr>(E))
- D = ME->getMemberDecl();
- else if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- D = DRE->getDecl();
+ const NamedDecl *ND = nullptr;
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+ ND = DRE->getDecl();
+ else if (const auto *ME = dyn_cast<MemberExpr>(E))
+ ND = ME->getMemberDecl();
else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E))
- D = IRE->getDecl();
+ return IRE->getDecl()->getNextIvar() == nullptr;
+
+ if (!ND)
+ return false;
- return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(),
- StrictFlexArraysLevel,
- IgnoreTemplateOrMacroSubstitution);
+ // A flexible array member must be the last member in the class.
+ // FIXME: If the base type of the member expr is not FD->getParent(),
+ // this should not be treated as a flexible array member access.
+ if (const auto *FD = dyn_cast<FieldDecl>(ND)) {
+ // GCC treats an array memeber of a union as an FAM if the size is one or
+ // zero.
+ if (CAT) {
+ llvm::APInt Size = CAT->getSize();
+ if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
+ return true;
+ }
+
+ // Don't consider sizes resulting from macro expansions or template argument
+ // substitution to form C89 tail-padded arrays.
+ if (IgnoreTemplateOrMacroSubstitution) {
+ TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
+ while (TInfo) {
+ TypeLoc TL = TInfo->getTypeLoc();
+ // Look through typedefs.
+ if (TypedefTypeLoc TTL = TL.getAsAdjusted<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;
+ }
+ }
+
+ RecordDecl::field_iterator FI(
+ DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
+ return ++FI == FD->getParent()->field_end();
+ }
+
+ return false;
}
const ValueDecl *
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index bf984861bccb5cc..3f68aa2c953c74b 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -853,57 +853,6 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
}
}
- if (IsDynamic) {
- LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
- getLangOpts().getStrictFlexArraysLevel();
- const Expr *Base = E->IgnoreParenImpCasts();
-
- if (FieldDecl *FD = FindCountedByField(Base, StrictFlexArraysLevel)) {
- const auto *ME = dyn_cast<MemberExpr>(Base);
- llvm::Value *ObjectSize = nullptr;
-
- if (!ME) {
- const auto *DRE = dyn_cast<DeclRefExpr>(Base);
- ValueDecl *VD = nullptr;
-
- ObjectSize = ConstantInt::get(
- ResType,
- getContext().getTypeSize(DRE->getType()->getPointeeType()) / 8,
- true);
-
- if (auto *RD = DRE->getType()->getPointeeType()->getAsRecordDecl())
- VD = RD->getLastField();
-
- Expr *ICE = ImplicitCastExpr::Create(
- getContext(), DRE->getType(), CK_LValueToRValue,
- const_cast<Expr *>(cast<Expr>(DRE)), nullptr, VK_PRValue,
- FPOptionsOverride());
- ME = MemberExpr::CreateImplicit(getContext(), ICE, true, VD,
- VD->getType(), VK_LValue, OK_Ordinary);
- }
-
- // At this point, we know that \p ME is a flexible array member.
- const auto *ArrayTy = getContext().getAsArrayType(ME->getType());
- unsigned Size = getContext().getTypeSize(ArrayTy->getElementType());
-
- llvm::Value *CountField =
- EmitAnyExprToTemp(MemberExpr::CreateImplicit(
- getContext(), const_cast<Expr *>(ME->getBase()),
- ME->isArrow(), FD, FD->getType(), VK_LValue,
- OK_Ordinary))
- .getScalarVal();
-
- llvm::Value *Mul = Builder.CreateMul(
- CountField, llvm::ConstantInt::get(CountField->getType(), Size / 8));
- Mul = Builder.CreateZExtOrTrunc(Mul, ResType);
-
- if (ObjectSize)
- return Builder.CreateAdd(ObjectSize, Mul);
-
- return Mul;
- }
- }
-
// LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
// evaluate E for side-effects. In either case, we shouldn't lower to
// @llvm.objectsize.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 54a1d300a9ac738..1b6a2c1fc49967c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -30,7 +30,6 @@
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
@@ -932,31 +931,16 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
if (CE->getCastKind() == CK_ArrayToPointerDecay &&
!CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(),
StrictFlexArraysLevel)) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
-
IndexedType = CE->getSubExpr()->getType();
const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
return CGF.Builder.getInt(CAT->getSize());
-
- if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
+ else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
return CGF.getVLASize(VAT).NumElts;
// Ignore pass_object_size here. It's not applicable on decayed po...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/68603
More information about the cfe-commits
mailing list