[clang] [clang] Avoid re-evaluating field bitwidth (PR #117732)

via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 08:11:22 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>



---

Patch is 35.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/117732.diff


15 Files Affected:

- (modified) clang/include/clang/AST/Decl.h (+22-4) 
- (modified) clang/include/clang/AST/DeclObjC.h (+27-7) 
- (modified) clang/include/clang/Sema/Sema.h (+1-1) 
- (modified) clang/lib/AST/ASTContext.cpp (+30-53) 
- (modified) clang/lib/AST/ASTImporter.cpp (+1-1) 
- (modified) clang/lib/AST/Decl.cpp (+18-5) 
- (modified) clang/lib/AST/DeclObjC.cpp (+22-12) 
- (modified) clang/lib/CodeGen/CGObjCMac.cpp (+7-7) 
- (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+2-1) 
- (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+3-3) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+4-8) 
- (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+3-3) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+36-35) 
- (modified) clang/lib/Sema/SemaDeclObjC.cpp (+13-10) 
- (modified) clang/lib/Sema/SemaLambda.cpp (+1-1) 


``````````diff
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 8c39ef3d5a9fa6..db3c86a09bfb49 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3089,17 +3089,27 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
     // Active member if ISK is ISK_CapturedVLAType.
     const VariableArrayType *CapturedVLAType;
   };
+  unsigned BitWidthValue = 0;
 
 protected:
   FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
             SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
-            TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
-            InClassInitStyle InitStyle)
+            TypeSourceInfo *TInfo, bool Mutable, InClassInitStyle InitStyle)
+      : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
+        Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
+        CachedFieldIndex(0), Init() {}
+
+  FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+            SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
+            TypeSourceInfo *TInfo, Expr *BW, unsigned BitWidthValue,
+            bool Mutable, InClassInitStyle InitStyle)
       : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
         Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
         CachedFieldIndex(0), Init() {
-    if (BW)
+    if (BW) {
       setBitWidth(BW);
+      this->BitWidthValue = BitWidthValue;
+    }
   }
 
 public:
@@ -3109,7 +3119,15 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
   static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
                            SourceLocation StartLoc, SourceLocation IdLoc,
                            const IdentifierInfo *Id, QualType T,
-                           TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+                           TypeSourceInfo *TInfo, Expr *BW,
+                           unsigned BitWidthValue, bool Mutable,
+                           InClassInitStyle InitStyle);
+
+  /// For non-bit-fields.
+  static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
+                           SourceLocation StartLoc, SourceLocation IdLoc,
+                           const IdentifierInfo *Id, QualType T,
+                           TypeSourceInfo *TInfo, bool Mutable,
                            InClassInitStyle InitStyle);
 
   static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index 4663603f797545..17bccfda784fed 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1960,8 +1960,15 @@ class ObjCIvarDecl : public FieldDecl {
   ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
                SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
                TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
-               bool synthesized)
-      : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
+               unsigned BWValue, bool synthesized)
+      : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, BWValue,
+                  /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
+        DeclAccess(ac), Synthesized(synthesized) {}
+
+  ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
+               SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
+               TypeSourceInfo *TInfo, AccessControl ac, bool synthesized)
+      : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo,
                   /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
         DeclAccess(ac), Synthesized(synthesized) {}
 
@@ -1970,7 +1977,8 @@ class ObjCIvarDecl : public FieldDecl {
                               SourceLocation StartLoc, SourceLocation IdLoc,
                               const IdentifierInfo *Id, QualType T,
                               TypeSourceInfo *TInfo, AccessControl ac,
-                              Expr *BW = nullptr, bool synthesized = false);
+                              Expr *BW = nullptr, unsigned BWValue = 0,
+                              bool synthesized = false);
 
   static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
 
@@ -2028,11 +2036,19 @@ class ObjCIvarDecl : public FieldDecl {
 /// Represents a field declaration created by an \@defs(...).
 class ObjCAtDefsFieldDecl : public FieldDecl {
   ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
-                      SourceLocation IdLoc, IdentifierInfo *Id,
-                      QualType T, Expr *BW)
+                      SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+                      Expr *BW, unsigned BWValue)
+      : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
+                  /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
+                  BW, BWValue, /*Mutable=*/false,
+                  /*HasInit=*/ICIS_NoInit) {}
+
+  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
+                      SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
       : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
                   /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
-                  BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
+                  /*Mutable=*/false,
+                  /*HasInit=*/ICIS_NoInit) {}
 
   void anchor() override;
 
@@ -2040,7 +2056,11 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
   static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
-                                     QualType T, Expr *BW);
+                                     QualType T, Expr *BW, unsigned BWValue);
+  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation StartLoc,
+                                     SourceLocation IdLoc, IdentifierInfo *Id,
+                                     QualType T);
 
   static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C,
                                                  GlobalDeclID ID);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 24abd5d95dd844..5c82a75f491e37 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4277,7 +4277,7 @@ class Sema final : public SemaBase {
   /// Returns false on success.
   ExprResult VerifyBitField(SourceLocation FieldLoc,
                             const IdentifierInfo *FieldName, QualType FieldTy,
-                            bool IsMsStruct, Expr *BitWidth);
+                            bool IsMsStruct, Expr *BitWidth, unsigned &BWV);
 
   /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag
   /// enum. If AllowMask is true, then we also allow the complement of a valid
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 80e8c5b9df58e7..26631f9a5c7f9b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7969,11 +7969,10 @@ TypedefDecl *ASTContext::getCFConstantStringDecl() const {
 
   // Create fields
   for (unsigned i = 0; i < Count; ++i) {
-    FieldDecl *Field =
-        FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(),
-                          SourceLocation(), &Idents.get(Fields[i].Name),
-                          Fields[i].Type, /*TInfo=*/nullptr,
-                          /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        *this, CFConstantStringTagDecl, SourceLocation(), SourceLocation(),
+        &Idents.get(Fields[i].Name), Fields[i].Type, /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     CFConstantStringTagDecl->addDecl(Field);
   }
@@ -8039,7 +8038,7 @@ QualType ASTContext::getBlockDescriptorType() const {
     FieldDecl *Field = FieldDecl::Create(
         *this, RD, SourceLocation(), SourceLocation(),
         &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
-        /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     RD->addDecl(Field);
   }
@@ -8078,7 +8077,6 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
     FieldDecl *Field = FieldDecl::Create(
         *this, RD, SourceLocation(), SourceLocation(),
         &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
-        /*BitWidth=*/nullptr,
         /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     RD->addDecl(Field);
@@ -9436,15 +9434,11 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                         VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
+        SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
+        /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9489,14 +9483,10 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        *Context, VaListTagDecl, SourceLocation(), SourceLocation(),
+        &Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9547,15 +9537,11 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                         VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
+        SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
+        /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9599,16 +9585,12 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
   VaListDecl->startDefinition();
 
   // void * __ap;
-  FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                       VaListDecl,
-                                       SourceLocation(),
-                                       SourceLocation(),
-                                       &Context->Idents.get("__ap"),
-                                       Context->getPointerType(Context->VoidTy),
-                                       /*TInfo=*/nullptr,
-                                       /*BitWidth=*/nullptr,
-                                       /*Mutable=*/false,
-                                       ICIS_NoInit);
+  FieldDecl *Field = FieldDecl::Create(
+      const_cast<ASTContext &>(*Context), VaListDecl, SourceLocation(),
+      SourceLocation(), &Context->Idents.get("__ap"),
+      Context->getPointerType(Context->VoidTy),
+      /*TInfo=*/nullptr,
+      /*Mutable=*/false, ICIS_NoInit);
   Field->setAccess(AS_public);
   VaListDecl->addDecl(Field);
 
@@ -9650,15 +9632,11 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                         VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
+        SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
+        /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9704,7 +9682,6 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
         const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
         SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
         /*TInfo=*/nullptr,
-        /*BitWidth=*/nullptr,
         /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index a0cd57e2e5ee0d..517d3332d07e07 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4231,7 +4231,7 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
   FieldDecl *ToField;
   if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
                               ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
-                              ToType, ToTInfo, ToBitWidth, D->isMutable(),
+                              ToType, ToTInfo, ToBitWidth, 0, D->isMutable(),
                               D->getInClassInitStyle()))
     return ToField;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 741e908cf9bc56..e92cc00b23ed5c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4555,16 +4555,26 @@ unsigned FunctionDecl::getODRHash() {
 FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
                              SourceLocation StartLoc, SourceLocation IdLoc,
                              const IdentifierInfo *Id, QualType T,
-                             TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+                             TypeSourceInfo *TInfo, Expr *BW,
+                             unsigned BitWidthValue, bool Mutable,
                              InClassInitStyle InitStyle) {
   return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
-                               BW, Mutable, InitStyle);
+                               BW, BitWidthValue, Mutable, InitStyle);
+}
+
+FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
+                             SourceLocation StartLoc, SourceLocation IdLoc,
+                             const IdentifierInfo *Id, QualType T,
+                             TypeSourceInfo *TInfo, bool Mutable,
+                             InClassInitStyle InitStyle) {
+  return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
+                               nullptr, 0, Mutable, InitStyle);
 }
 
 FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
-                               SourceLocation(), nullptr, QualType(), nullptr,
-                               nullptr, false, ICIS_NoInit);
+  return new (C, ID)
+      FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr,
+                QualType(), nullptr, false, ICIS_NoInit);
 }
 
 bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -4601,6 +4611,9 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) {
 
 unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
   assert(isBitField() && "not a bitfield");
+  // FIXME: 0 might be the actual value of the bitwidth.
+  if (BitWidthValue != 0)
+    return BitWidthValue;
   return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
 }
 
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 5c107325df30c6..a2ed670cd941ca 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -1833,7 +1833,8 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
                                    SourceLocation IdLoc,
                                    const IdentifierInfo *Id, QualType T,
                                    TypeSourceInfo *TInfo, AccessControl ac,
-                                   Expr *BW, bool synthesized) {
+                                   Expr *BW, unsigned BWValue,
+                                   bool synthesized) {
   if (DC) {
     // Ivar's can only appear in interfaces, implementations (via synthesized
     // properties), and class extensions (via direct declaration, or synthesized
@@ -1861,13 +1862,13 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
   }
 
   return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
-                                  synthesized);
+                                  BWValue, synthesized);
 }
 
 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
-                                  nullptr, QualType(), nullptr,
-                                  ObjCIvarDecl::None, nullptr, false);
+  return new (C, ID)
+      ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
+                   QualType(), nullptr, ObjCIvarDecl::None, false);
 }
 
 ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {
@@ -1905,18 +1906,27 @@ QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
 
 void ObjCAtDefsFieldDecl::anchor() {}
 
-ObjCAtDefsFieldDecl
-*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
-                             SourceLocation StartLoc,  SourceLocation IdLoc,
-                             IdentifierInfo *Id, QualType T, Expr *BW) {
-  return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
+ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation IdLoc,
+                                                 IdentifierInfo *Id, QualType T,
+                                                 Expr *BW, unsigned BWValue) {
+  return new (C, DC)
+      ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW, BWValue);
+}
+
+ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation IdLoc,
+               ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/117732


More information about the cfe-commits mailing list