[llvm] 9fd4b5f - [FileCheck] Implement -dump-input-filter

Joel E. Denny via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 10 08:04:31 PDT 2020


Author: Joel E. Denny
Date: 2020-07-10T11:02:11-04:00
New Revision: 9fd4b5faacbdfb887389c9ac246efa23be1cd334

URL: https://github.com/llvm/llvm-project/commit/9fd4b5faacbdfb887389c9ac246efa23be1cd334
DIFF: https://github.com/llvm/llvm-project/commit/9fd4b5faacbdfb887389c9ac246efa23be1cd334.diff

LOG: [FileCheck] Implement -dump-input-filter

This makes the input dump filtering implemented by D82203 more
configurable.  D82203 enables filtering out everything but the initial
input lines of error diagnostics (plus some context).  This patch
enables including any line with any kind of annotation.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D83097

Added: 
    

Modified: 
    llvm/test/FileCheck/dump-input-filter.txt
    llvm/utils/FileCheck/FileCheck.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/FileCheck/dump-input-filter.txt b/llvm/test/FileCheck/dump-input-filter.txt
index f1b8cf543d05..29f43ff1ce80 100644
--- a/llvm/test/FileCheck/dump-input-filter.txt
+++ b/llvm/test/FileCheck/dump-input-filter.txt
@@ -115,6 +115,102 @@
 ; ALL-NEXT: check:3'0     ~~~
 ; ALL-NEXT: >>>>>>
 
+;      ANNOTATION-FULL: <<<<<<
+; ANNOTATION-FULL-NEXT:            1: start
+; ANNOTATION-FULL-NEXT: check:1       ^~~~~
+; ANNOTATION-FULL-NEXT:            2: foo0
+; ANNOTATION-FULL-NEXT:            3: foo1
+; ANNOTATION-FULL-NEXT:            .
+; ANNOTATION-FULL-NEXT:            .
+; ANNOTATION-FULL-NEXT:            .
+; ANNOTATION-FULL-NEXT:           10: foo8
+; ANNOTATION-FULL-NEXT:           11: foo9
+; ANNOTATION-FULL-NEXT:           12: hello
+; ANNOTATION-FULL-NEXT: check:2       ^~~~~
+; ANNOTATION-FULL-NEXT:           13: foo0
+; ANNOTATION-FULL-NEXT: check:3'0     X~~~ error: no match found
+; ANNOTATION-FULL-NEXT:           14: foo1
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           15: foo2
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           16: foo3
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           17: foo4
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           18: foo5
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           19: foo6
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           20: foo7
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           21: foo8
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           22: foo9
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           23: word
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT: check:3'1     ?     possible intended match
+; ANNOTATION-FULL-NEXT:           24: foo0
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           25: foo1
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           26: foo2
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           27: foo3
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           28: foo4
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           29: foo5
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           30: foo6
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           31: foo7
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           32: foo8
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           33: foo9
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~~
+; ANNOTATION-FULL-NEXT:           34: end
+; ANNOTATION-FULL-NEXT: check:3'0     ~~~
+; ANNOTATION-FULL-NEXT: >>>>>>
+
+;      ANNOTATION: <<<<<<
+; ANNOTATION-NEXT:            1: start
+; ANNOTATION-NEXT: check:1       ^~~~~
+; ANNOTATION-NEXT:            2: foo0
+; ANNOTATION-NEXT:            3: foo1
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:           10: foo8
+; ANNOTATION-NEXT:           11: foo9
+; ANNOTATION-NEXT:           12: hello
+; ANNOTATION-NEXT: check:2       ^~~~~
+; ANNOTATION-NEXT:           13: foo0
+; ANNOTATION-NEXT: check:3'0     X~~~ error: no match found
+; ANNOTATION-NEXT:           14: foo1
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT:           15: foo2
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:           21: foo8
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT:           22: foo9
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT:           23: word
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT: check:3'1     ?     possible intended match
+; ANNOTATION-NEXT:           24: foo0
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT:           25: foo1
+; ANNOTATION-NEXT: check:3'0     ~~~~
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT:            .
+; ANNOTATION-NEXT: >>>>>>
+
 ;      ERROR: <<<<<<
 ; ERROR-NEXT:            .
 ; ERROR-NEXT:            .
@@ -148,28 +244,149 @@
 ; ERROR-NEXT: >>>>>>
 
 ;--------------------------------------------------
-; Check how -dump-input affects filter.
+; Check -dump-input-filter=<bad value>.
+;--------------------------------------------------
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=foobar \
+; RUN: | FileCheck %s -match-full-lines -check-prefix=BADVAL
+
+BADVAL: {{F|f}}ile{{C|c}}heck{{.*}}: for the --dump-input-filter option: Cannot find option named 'foobar'!
+
+;--------------------------------------------------
+; Check -dump-input-filter explicit values.
+;--------------------------------------------------
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=all \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=annotation-full \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION-FULL
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=annotation \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=error \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ERROR
+
+;--------------------------------------------------
+; Check -dump-input-filter defaults.
 ;--------------------------------------------------
 
-; no -dump-input => include errors.
+; no -dump-input => -dump-input-filter=error
 ; RUN: %ProtectFileCheckOutput \
 ; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
 ; RUN: | FileCheck %s -match-full-lines -check-prefixes=ERROR
 
-; -dump-input=fail => include errors.
+; -dump-input=fail => -dump-input-filter=error
 ; RUN: %ProtectFileCheckOutput \
 ; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
 ; RUN:               -dump-input=fail \
 ; RUN: | FileCheck %s -match-full-lines -check-prefixes=ERROR
 
-; -dump-input=always => include all.
+; -dump-input=always => -dump-input-filter=all
 ; RUN: %ProtectFileCheckOutput \
 ; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
 ; RUN:               -dump-input=always \
 ; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL
 
 ;--------------------------------------------------
-; Check that other kinds of errors are included by -dump-input=fail.
+; Check multiple -dump-input-filter options.
+;
+; This might occur when a test author specifies -dump-input-filter on a specific
+; FileCheck call while a test runner specifies -dump-input-filter in
+; FILECHECK_OPTS, but check the behavior generally.
+;
+; The value providing the most information wins.
+;--------------------------------------------------
+
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+; Check duplicate.
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+
+; all, all => all
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=all -dump-input-filter=all \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL
+
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+; Check precedence.
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+
+; all, annotation-full => all
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=all -dump-input-filter=annotation-full \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL
+
+; annotation-full, annotation => annotation-full
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=annotation-full \
+; RUN:               -dump-input-filter=annotation \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION-FULL
+
+; annotation, error => annotation
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=annotation -dump-input-filter=error \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION
+
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+; Check that order doesn't matter.
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+
+; error, annotation => annotation
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=error -dump-input-filter=annotation \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION
+
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+; Check that FILECHECK_OPTS isn't handled 
diff erently.
+;- - - - - - - - - - - - - - - - - - - - - - - - -
+
+; annotation, error => annotation
+; RUN: %ProtectFileCheckOutput FILECHECK_OPTS=-dump-input-filter=annotation \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=error \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION
+
+; error, annotation => annotation
+; RUN: %ProtectFileCheckOutput FILECHECK_OPTS=-dump-input-filter=error \
+; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \
+; RUN:               -dump-input-filter=annotation \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION
+
+;--------------------------------------------------
+; Check the case where all input lines are filtered out.
+;--------------------------------------------------
+
+; RUN: echo 'CHECK: hello' > %t.good.chk
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: FileCheck -dump-input=always -dump-input-filter=error -vv %t.good.chk \
+; RUN:           < %t.in 2>&1 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=EMPTY
+
+;      EMPTY: <<<<<<
+; EMPTY-NEXT:          .
+; EMPTY-NEXT:          .
+; EMPTY-NEXT:          .
+; EMPTY-NEXT: >>>>>>
+
+;--------------------------------------------------
+; Check that other kinds of errors are included by -dump-input-filter=error.
 ;
 ; "error: no match found" and "possible intended match" are checked above.
 ;--------------------------------------------------
@@ -182,7 +399,7 @@
 ; RUN: echo 'CHECK-NOT: foo' > %t.not-err.chk
 
 ; RUN: %ProtectFileCheckOutput \
-; RUN: not FileCheck -dump-input-context=0 -dump-input=fail \
+; RUN: not FileCheck -dump-input-context=0 -dump-input-filter=error \
 ; RUN:               %t.not-err.chk < %t.not-err.in 2>&1 \
 ; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOT-ERR
 
@@ -200,9 +417,9 @@
 ; RUN: echo 'CHECK-NEXT: bar' >> %t.next-err.chk
 
 ; RUN: %ProtectFileCheckOutput \
-; RUN: not FileCheck -dump-input-context=0 -dump-input=fail \
+; RUN: not FileCheck -dump-input-context=0 -dump-input-filter=error \
 ; RUN:               %t.next-err.chk < %t.next-err.in 2>&1 \
 ; RUN: | FileCheck %s -match-full-lines -check-prefixes=NEXT-ERR
 
 ;      NEXT-ERR:         3: bar
-; NEXT-ERR-NEXT: next:2     !~~ error: match on wrong line
+; NEXT-ERR-NEXT: next:2     !~~ error: match on wrong line
\ No newline at end of file

diff  --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index ec2556074aee..8bf1dd2e9b49 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -128,11 +128,38 @@ static cl::list<DumpInputValue> DumpInputs(
                clEnumValN(DumpInputFail, "fail", "Dump input on failure"),
                clEnumValN(DumpInputNever, "never", "Never dump input")));
 
+// The order of DumpInputFilterValue members affects their precedence, as
+// documented for -dump-input-filter below.
+enum DumpInputFilterValue {
+  DumpInputFilterError,
+  DumpInputFilterAnnotation,
+  DumpInputFilterAnnotationFull,
+  DumpInputFilterAll
+};
+
+static cl::list<DumpInputFilterValue> DumpInputFilters(
+    "dump-input-filter",
+    cl::desc("In the dump requested by -dump-input, print only input lines of\n"
+             "kind <kind> plus any context specified by -dump-input-context.\n"
+             "When there are multiple occurrences of this option, the <kind>\n"
+             "that appears earliest in the list below has precedence.  The\n"
+             "default is 'error' when -dump-input=fail, and it's 'all' when\n"
+             "-dump-input=always.\n"),
+    cl::value_desc("kind"),
+    cl::values(clEnumValN(DumpInputFilterAll, "all", "All input lines"),
+               clEnumValN(DumpInputFilterAnnotationFull, "annotation-full",
+                          "Input lines with annotations"),
+               clEnumValN(DumpInputFilterAnnotation, "annotation",
+                          "Input lines with starting points of annotations"),
+               clEnumValN(DumpInputFilterError, "error",
+                          "Input lines with starting points of error "
+                          "annotations")));
+
 static cl::list<unsigned> DumpInputContexts(
     "dump-input-context", cl::value_desc("N"),
-    cl::desc("In the dump requested by -dump-input=fail, print <N> input\n"
-             "lines before and <N> input lines after the starting line of\n"
-             "any error diagnostic.  When there are multiple occurrences of\n"
+    cl::desc("In the dump requested by -dump-input, print <N> input lines\n"
+             "before and <N> input lines after any lines specified by\n"
+             "-dump-input-filter.  When there are multiple occurrences of\n"
              "this option, the largest specified <N> has precedence.  The\n"
              "default is 5.\n"));
 
@@ -158,8 +185,7 @@ struct MarkerStyle {
   raw_ostream::Colors Color;
   /// A note to follow the marker, or empty string if none.
   std::string Note;
-  /// Does this marker indicate inclusion by the input filter implied by
-  /// -dump-input=fail?
+  /// Does this marker indicate inclusion by -dump-input-filter=error?
   bool FiltersAsError;
   MarkerStyle() {}
   MarkerStyle(char Lead, raw_ostream::Colors Color,
@@ -201,7 +227,8 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) {
      << "\n"
      << "Related command-line options:\n"
      << "  - -dump-input=<value> enables or disables the input dump\n"
-     << "  - -dump-input-context=<N> adjusts the context of errors\n"
+     << "  - -dump-input-filter=<kind> filters the input lines\n"
+     << "  - -dump-input-context=<N> adjusts the context of filtered lines\n"
      << "  - -v and -vv add more annotations\n"
      << "  - -color forces colors to be enabled both in the dump and below\n"
      << "  - -help documents the above options in more detail\n"
@@ -251,7 +278,7 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) {
   OS << "  - ";
   WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "...";
   OS << "    indicates elided input lines and annotations, as specified by\n"
-     << "           -dump-input=fail and -dump-input-context\n";
+     << "           -dump-input-filter and -dump-input-context\n";
 
   // Colors.
   OS << "  - colors ";
@@ -416,15 +443,28 @@ BuildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
 }
 
 static unsigned FindInputLineInFilter(
-    bool FilterOnError, unsigned CurInputLine,
+    DumpInputFilterValue DumpInputFilter, unsigned CurInputLine,
     const std::vector<InputAnnotation>::iterator &AnnotationBeg,
     const std::vector<InputAnnotation>::iterator &AnnotationEnd) {
-  if (!FilterOnError)
+  if (DumpInputFilter == DumpInputFilterAll)
     return CurInputLine;
   for (auto AnnotationItr = AnnotationBeg; AnnotationItr != AnnotationEnd;
        ++AnnotationItr) {
-    if (AnnotationItr->IsFirstLine && AnnotationItr->Marker.FiltersAsError)
+    switch (DumpInputFilter) {
+    case DumpInputFilterAll:
+      llvm_unreachable("unexpected DumpInputFilterAll");
+      break;
+    case DumpInputFilterAnnotationFull:
       return AnnotationItr->InputLine;
+    case DumpInputFilterAnnotation:
+      if (AnnotationItr->IsFirstLine)
+        return AnnotationItr->InputLine;
+      break;
+    case DumpInputFilterError:
+      if (AnnotationItr->IsFirstLine && AnnotationItr->Marker.FiltersAsError)
+        return AnnotationItr->InputLine;
+      break;
+    }
   }
   return UINT_MAX;
 }
@@ -449,7 +489,7 @@ static void DumpEllipsisOrElidedLines(raw_ostream &OS, std::string &ElidedLines,
 }
 
 static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
-                               bool DumpInputFilterOnError,
+                               DumpInputFilterValue DumpInputFilter,
                                unsigned DumpInputContext,
                                StringRef InputFileText,
                                std::vector<InputAnnotation> &Annotations,
@@ -540,7 +580,7 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
 
     // Compute the previous and next line included by the filter.
     if (NextLineInFilter < Line)
-      NextLineInFilter = FindInputLineInFilter(DumpInputFilterOnError, Line,
+      NextLineInFilter = FindInputLineInFilter(DumpInputFilter, Line,
                                                AnnotationItr, AnnotationEnd);
     assert(NextLineInFilter && "expected NextLineInFilter to be computed");
     if (NextLineInFilter == Line)
@@ -548,7 +588,7 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
 
     // Elide this input line and its annotations if it's not within the
     // context specified by -dump-input-context of an input line included by
-    // the dump filter.  However, in case the resulting ellipsis would occupy
+    // -dump-input-filter.  However, in case the resulting ellipsis would occupy
     // more lines than the input lines and annotations it elides, buffer the
     // elided lines and annotations so we can print them instead.
     raw_ostream *LineOS = &OS;
@@ -661,7 +701,13 @@ int main(int argc, char **argv) {
       DumpInputs.empty()
           ? DumpInputFail
           : *std::max_element(DumpInputs.begin(), DumpInputs.end());
-  bool DumpInputFilterOnError = DumpInput == DumpInputFail;
+  DumpInputFilterValue DumpInputFilter;
+  if (DumpInputFilters.empty())
+    DumpInputFilter = DumpInput == DumpInputAlways ? DumpInputFilterAll
+                                                   : DumpInputFilterError;
+  else
+    DumpInputFilter =
+        *std::max_element(DumpInputFilters.begin(), DumpInputFilters.end());
   unsigned DumpInputContext = DumpInputContexts.empty()
                                   ? 5
                                   : *std::max_element(DumpInputContexts.begin(),
@@ -799,7 +845,7 @@ int main(int argc, char **argv) {
     unsigned LabelWidth;
     BuildInputAnnotations(SM, CheckFileBufferID, ImpPatBufferIDRange, Diags,
                           Annotations, LabelWidth);
-    DumpAnnotatedInput(errs(), Req, DumpInputFilterOnError, DumpInputContext,
+    DumpAnnotatedInput(errs(), Req, DumpInputFilter, DumpInputContext,
                        InputFileText, Annotations, LabelWidth);
   }
 


        


More information about the llvm-commits mailing list