Skip to content

Commit cca4d6c

Browse files
authored
Revert counted_by attribute feature (llvm#75857)
There are many issues that popped up with the counted_by feature. The patch llvm#73730 has grown too large and approval is blocking Linux testing. Includes reverts of: commit 769bc11 ("[Clang] Implement the 'counted_by' attribute (llvm#68750)") commit bc09ec6 ("[CodeGen] Revamp counted_by calculations (llvm#70606)") commit 1a09cfb ("[Clang] counted_by attr can apply only to C99 flexible array members (llvm#72347)") commit a76adfb ("[NFC][Clang] Refactor code to calculate flexible array member size (llvm#72790)") commit d8447c7 ("[Clang] Correct handling of negative and out-of-bounds indices (llvm#71877)") Partial commit b31cd07 ("[Clang] Regenerate test checks (NFC)") Closes llvm#73168 Closes llvm#75173
1 parent e777317 commit cca4d6c

21 files changed

+89
-1470
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,6 @@ C Language Changes
199199
- ``structs``, ``unions``, and ``arrays`` that are const may now be used as
200200
constant expressions. This change is more consistent with the behavior of
201201
GCC.
202-
- Clang now supports the C-only attribute ``counted_by``. When applied to a
203-
struct's flexible array member, it points to the struct field that holds the
204-
number of elements in the flexible array member. This information can improve
205-
the results of the array bound sanitizer and the
206-
``__builtin_dynamic_object_size`` builtin.
207202
- Enums will now be represented in TBAA metadata using their actual underlying
208203
integer type. Previously they were treated as chars, which meant they could
209204
alias with all other types.

clang/include/clang/AST/Decl.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4332,30 +4332,6 @@ class RecordDecl : public TagDecl {
43324332
return field_begin() == field_end();
43334333
}
43344334

4335-
FieldDecl *getLastField() {
4336-
FieldDecl *FD = nullptr;
4337-
for (FieldDecl *Field : fields())
4338-
FD = Field;
4339-
return FD;
4340-
}
4341-
const FieldDecl *getLastField() const {
4342-
return const_cast<RecordDecl *>(this)->getLastField();
4343-
}
4344-
4345-
template <typename Functor>
4346-
const FieldDecl *findFieldIf(Functor &Pred) const {
4347-
for (const Decl *D : decls()) {
4348-
if (const auto *FD = dyn_cast<FieldDecl>(D); FD && Pred(FD))
4349-
return FD;
4350-
4351-
if (const auto *RD = dyn_cast<RecordDecl>(D))
4352-
if (const FieldDecl *FD = RD->findFieldIf(Pred))
4353-
return FD;
4354-
}
4355-
4356-
return nullptr;
4357-
}
4358-
43594335
/// Note that the definition of this type is now complete.
43604336
virtual void completeDefinition();
43614337

clang/include/clang/AST/DeclBase.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "clang/AST/SelectorLocationsKind.h"
2020
#include "clang/Basic/IdentifierTable.h"
2121
#include "clang/Basic/LLVM.h"
22-
#include "clang/Basic/LangOptions.h"
2322
#include "clang/Basic/SourceLocation.h"
2423
#include "clang/Basic/Specifiers.h"
2524
#include "llvm/ADT/ArrayRef.h"
@@ -489,15 +488,6 @@ class alignas(8) Decl {
489488
// Return true if this is a FileContext Decl.
490489
bool isFileContextDecl() const;
491490

492-
/// Whether it resembles a flexible array member. This is a static member
493-
/// because we want to be able to call it with a nullptr. That allows us to
494-
/// perform non-Decl specific checks based on the object's type and strict
495-
/// flex array level.
496-
static bool isFlexibleArrayMemberLike(
497-
ASTContext &Context, const Decl *D, QualType Ty,
498-
LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
499-
bool IgnoreTemplateOrMacroSubstitution);
500-
501491
ASTContext &getASTContext() const LLVM_READONLY;
502492

503493
/// Helper to get the language options from the ASTContext.

clang/include/clang/Basic/Attr.td

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,24 +4331,6 @@ def AvailableOnlyInDefaultEvalMethod : InheritableAttr {
43314331
let Documentation = [Undocumented];
43324332
}
43334333

4334-
def CountedBy : InheritableAttr {
4335-
let Spellings = [Clang<"counted_by">];
4336-
let Subjects = SubjectList<[Field]>;
4337-
let Args = [IdentifierArgument<"CountedByField">];
4338-
let Documentation = [CountedByDocs];
4339-
let LangOpts = [COnly];
4340-
// FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl
4341-
// isn't yet available due to the fact that we're still parsing the
4342-
// structure. Maybe that code could be changed sometime in the future.
4343-
code AdditionalMembers = [{
4344-
private:
4345-
SourceRange CountedByFieldLoc;
4346-
public:
4347-
SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; }
4348-
void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; }
4349-
}];
4350-
}
4351-
43524334
def PreferredType: InheritableAttr {
43534335
let Spellings = [Clang<"preferred_type">];
43544336
let Subjects = SubjectList<[BitField], ErrorDiag>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7500,72 +7500,6 @@ attribute, they default to the value ``65535``.
75007500
}];
75017501
}
75027502

7503-
def CountedByDocs : Documentation {
7504-
let Category = DocCatField;
7505-
let Content = [{
7506-
Clang supports the ``counted_by`` attribute on the flexible array member of a
7507-
structure in C. The argument for the attribute is the name of a field member in
7508-
the same structure holding the count of elements in the flexible array. This
7509-
information can be used to improve the results of the array bound sanitizer and
7510-
the ``__builtin_dynamic_object_size`` builtin.
7511-
7512-
For example, the following code:
7513-
7514-
.. code-block:: c
7515-
7516-
struct bar;
7517-
7518-
struct foo {
7519-
size_t count;
7520-
char other;
7521-
struct bar *array[] __attribute__((counted_by(count)));
7522-
};
7523-
7524-
specifies that the flexible array member ``array`` has the number of elements
7525-
allocated for it stored in ``count``. This establishes a relationship between
7526-
``array`` and ``count``. Specifically, ``p->array`` must have at least
7527-
``p->count`` number of elements available. It's the user's responsibility to
7528-
ensure that this relationship is maintained through changes to the structure.
7529-
7530-
In the following example, the allocated array erroneously has fewer elements
7531-
than what's specified by ``p->count``. This would result in an out-of-bounds
7532-
access not being detected.
7533-
7534-
.. code-block:: c
7535-
7536-
#define SIZE_INCR 42
7537-
7538-
struct foo *p;
7539-
7540-
void foo_alloc(size_t count) {
7541-
p = malloc(MAX(sizeof(struct foo),
7542-
offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
7543-
p->count = count + SIZE_INCR;
7544-
}
7545-
7546-
The next example updates ``p->count``, breaking the relationship requirement
7547-
that ``p->array`` must have at least ``p->count`` number of elements available:
7548-
7549-
.. code-block:: c
7550-
7551-
#define SIZE_INCR 42
7552-
7553-
struct foo *p;
7554-
7555-
void foo_alloc(size_t count) {
7556-
p = malloc(MAX(sizeof(struct foo),
7557-
offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
7558-
p->count = count;
7559-
}
7560-
7561-
void use_foo(int index) {
7562-
p->count += SIZE_INCR + 1; /* 'count' is now larger than the number of elements of 'array'. */
7563-
p->array[index] = 0; /* the sanitizer can't properly check if this is an out-of-bounds access. */
7564-
}
7565-
7566-
}];
7567-
}
7568-
75697503
def CoroOnlyDestroyWhenCompleteDocs : Documentation {
75707504
let Category = DocCatDecl;
75717505
let Content = [{

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6429,17 +6429,6 @@ def warn_superclass_variable_sized_type_not_at_end : Warning<
64296429
"field %0 can overwrite instance variable %1 with variable sized type %2"
64306430
" in superclass %3">, InGroup<ObjCFlexibleArray>;
64316431

6432-
def err_counted_by_attr_not_on_flexible_array_member : Error<
6433-
"'counted_by' only applies to C99 flexible array members">;
6434-
def err_counted_by_attr_refers_to_flexible_array : Error<
6435-
"'counted_by' cannot refer to the flexible array %0">;
6436-
def err_counted_by_must_be_in_structure : Error<
6437-
"field %0 in 'counted_by' not inside structure">;
6438-
def err_flexible_array_counted_by_attr_field_not_integer : Error<
6439-
"field %0 in 'counted_by' must be a non-boolean integer type">;
6440-
def note_flexible_array_counted_by_attr_field : Note<
6441-
"field %0 declared here">;
6442-
64436432
let CategoryName = "ARC Semantic Issue" in {
64446433

64456434
// ARC-mode diagnostics.

clang/include/clang/Sema/Sema.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4799,8 +4799,6 @@ class Sema final {
47994799
bool CheckAlwaysInlineAttr(const Stmt *OrigSt, const Stmt *CurSt,
48004800
const AttributeCommonInfo &A);
48014801

4802-
bool CheckCountedByAttr(Scope *Scope, const FieldDecl *FD);
4803-
48044802
/// Adjust the calling convention of a method to be the ABI default if it
48054803
/// wasn't specified explicitly. This handles method types formed from
48064804
/// function type typedefs and typename template arguments.
@@ -5644,7 +5642,6 @@ class Sema final {
56445642
CorrectionCandidateCallback &CCC,
56455643
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
56465644
ArrayRef<Expr *> Args = std::nullopt,
5647-
DeclContext *LookupCtx = nullptr,
56485645
TypoExpr **Out = nullptr);
56495646

56505647
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S,

clang/include/clang/Sema/TypoCorrection.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ class CorrectionCandidateCallback {
282282
public:
283283
static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
284284

285-
explicit CorrectionCandidateCallback(const IdentifierInfo *Typo = nullptr,
285+
explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr,
286286
NestedNameSpecifier *TypoNNS = nullptr)
287287
: Typo(Typo), TypoNNS(TypoNNS) {}
288288

@@ -319,7 +319,7 @@ class CorrectionCandidateCallback {
319319
/// this method.
320320
virtual std::unique_ptr<CorrectionCandidateCallback> clone() = 0;
321321

322-
void setTypoName(const IdentifierInfo *II) { Typo = II; }
322+
void setTypoName(IdentifierInfo *II) { Typo = II; }
323323
void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
324324

325325
// Flags for context-dependent keywords. WantFunctionLikeCasts is only
@@ -345,13 +345,13 @@ class CorrectionCandidateCallback {
345345
candidate.getCorrectionSpecifier() == TypoNNS;
346346
}
347347

348-
const IdentifierInfo *Typo;
348+
IdentifierInfo *Typo;
349349
NestedNameSpecifier *TypoNNS;
350350
};
351351

352352
class DefaultFilterCCC final : public CorrectionCandidateCallback {
353353
public:
354-
explicit DefaultFilterCCC(const IdentifierInfo *Typo = nullptr,
354+
explicit DefaultFilterCCC(IdentifierInfo *Typo = nullptr,
355355
NestedNameSpecifier *TypoNNS = nullptr)
356356
: CorrectionCandidateCallback(Typo, TypoNNS) {}
357357

@@ -365,10 +365,6 @@ class DefaultFilterCCC final : public CorrectionCandidateCallback {
365365
template <class C>
366366
class DeclFilterCCC final : public CorrectionCandidateCallback {
367367
public:
368-
explicit DeclFilterCCC(const IdentifierInfo *Typo = nullptr,
369-
NestedNameSpecifier *TypoNNS = nullptr)
370-
: CorrectionCandidateCallback(Typo, TypoNNS) {}
371-
372368
bool ValidateCandidate(const TypoCorrection &candidate) override {
373369
return candidate.getCorrectionDeclAs<C>();
374370
}

clang/lib/AST/ASTImporter.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9003,10 +9003,6 @@ class AttrImporter {
90039003
public:
90049004
AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {}
90059005

9006-
// Useful for accessing the imported attribute.
9007-
template <typename T> T *castAttrAs() { return cast<T>(ToAttr); }
9008-
template <typename T> const T *castAttrAs() const { return cast<T>(ToAttr); }
9009-
90109006
// Create an "importer" for an attribute parameter.
90119007
// Result of the 'value()' of that object is to be passed to the function
90129008
// 'importAttr', in the order that is expected by the attribute class.
@@ -9214,15 +9210,6 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
92149210
From->args_size());
92159211
break;
92169212
}
9217-
case attr::CountedBy: {
9218-
AI.cloneAttr(FromAttr);
9219-
const auto *CBA = cast<CountedByAttr>(FromAttr);
9220-
Expected<SourceRange> SR = Import(CBA->getCountedByFieldLoc()).get();
9221-
if (!SR)
9222-
return SR.takeError();
9223-
AI.castAttrAs<CountedByAttr>()->setCountedByFieldLoc(SR.get());
9224-
break;
9225-
}
92269213

92279214
default: {
92289215
// The default branch works for attributes that have no arguments to import.

clang/lib/AST/DeclBase.cpp

Lines changed: 1 addition & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "clang/AST/Type.h"
3030
#include "clang/Basic/IdentifierTable.h"
3131
#include "clang/Basic/LLVM.h"
32+
#include "clang/Basic/LangOptions.h"
3233
#include "clang/Basic/Module.h"
3334
#include "clang/Basic/ObjCRuntime.h"
3435
#include "clang/Basic/PartialDiagnostic.h"
@@ -410,79 +411,6 @@ bool Decl::isFileContextDecl() const {
410411
return DC && DC->isFileContext();
411412
}
412413

413-
bool Decl::isFlexibleArrayMemberLike(
414-
ASTContext &Ctx, const Decl *D, QualType Ty,
415-
LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
416-
bool IgnoreTemplateOrMacroSubstitution) {
417-
// For compatibility with existing code, we treat arrays of length 0 or
418-
// 1 as flexible array members.
419-
const auto *CAT = Ctx.getAsConstantArrayType(Ty);
420-
if (CAT) {
421-
using FAMKind = LangOptions::StrictFlexArraysLevelKind;
422-
423-
llvm::APInt Size = CAT->getSize();
424-
if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
425-
return false;
426-
427-
// GCC extension, only allowed to represent a FAM.
428-
if (Size.isZero())
429-
return true;
430-
431-
if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
432-
return false;
433-
434-
if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
435-
return false;
436-
} else if (!Ctx.getAsIncompleteArrayType(Ty)) {
437-
return false;
438-
}
439-
440-
if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D))
441-
return OID->getNextIvar() == nullptr;
442-
443-
const auto *FD = dyn_cast_if_present<FieldDecl>(D);
444-
if (!FD)
445-
return false;
446-
447-
if (CAT) {
448-
// GCC treats an array memeber of a union as an FAM if the size is one or
449-
// zero.
450-
llvm::APInt Size = CAT->getSize();
451-
if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
452-
return true;
453-
}
454-
455-
// Don't consider sizes resulting from macro expansions or template argument
456-
// substitution to form C89 tail-padded arrays.
457-
if (IgnoreTemplateOrMacroSubstitution) {
458-
TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
459-
while (TInfo) {
460-
TypeLoc TL = TInfo->getTypeLoc();
461-
462-
// Look through typedefs.
463-
if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
464-
const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
465-
TInfo = TDL->getTypeSourceInfo();
466-
continue;
467-
}
468-
469-
if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) {
470-
if (const Expr *SizeExpr =
471-
dyn_cast_if_present<IntegerLiteral>(CTL.getSizeExpr());
472-
!SizeExpr || SizeExpr->getExprLoc().isMacroID())
473-
return false;
474-
}
475-
476-
break;
477-
}
478-
}
479-
480-
// Test that the field is the last in the structure.
481-
RecordDecl::field_iterator FI(
482-
DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
483-
return ++FI == FD->getParent()->field_end();
484-
}
485-
486414
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
487415
if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
488416
return TUD;

0 commit comments

Comments
 (0)