https://github.com/Mick235711 updated 
https://github.com/llvm/llvm-project/pull/112289

>From b9911d5b997306376fcf5348a24f8bae7b71bfeb Mon Sep 17 00:00:00 2001
From: Yihe Li <winmiked...@hotmail.com>
Date: Tue, 15 Oct 2024 08:13:22 +0800
Subject: [PATCH] [clang] Generate note on declaration for nodiscard-related
 attributes

---
 clang/include/clang/AST/Expr.h                |  5 +-
 .../clang/Basic/DiagnosticSemaKinds.td        |  6 +-
 clang/lib/AST/Expr.cpp                        |  9 ++-
 clang/lib/Sema/SemaAvailability.cpp           |  8 +-
 clang/lib/Sema/SemaExpr.cpp                   |  2 +-
 clang/lib/Sema/SemaStmt.cpp                   | 77 +++++++++++++------
 .../dcl.attr/dcl.attr.nodiscard/p2.cpp        | 29 +++----
 .../dcl.attr/dcl.attr.nodiscard/p3.cpp        |  2 +-
 .../test/OpenMP/declare_variant_messages.cpp  |  2 +-
 clang/test/Sema/c2x-nodiscard.c               | 12 +--
 clang/test/Sema/unused-expr.c                 | 10 +--
 clang/test/SemaCXX/coroutines.cpp             |  2 +-
 clang/test/SemaCXX/warn-unused-result.cpp     | 26 +++----
 .../SemaObjC/method-warn-unused-attribute.m   |  6 +-
 14 files changed, 116 insertions(+), 80 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index cbe62411d11bff..4ba109cf059e43 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -3182,11 +3182,12 @@ class CallExpr : public Expr {
 
   /// Returns the WarnUnusedResultAttr that is either declared on the called
   /// function, or its return type declaration.
-  const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
+  std::pair<const Decl *, const Attr *>
+  getUnusedResultAttr(const ASTContext &Ctx) const;
 
   /// Returns true if this call expression should warn on unused results.
   bool hasUnusedResultAttr(const ASTContext &Ctx) const {
-    return getUnusedResultAttr(Ctx) != nullptr;
+    return getUnusedResultAttr(Ctx).second != nullptr;
   }
 
   SourceLocation getRParenLoc() const { return RParenLoc; }
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e78acc8dc8c57b..35e2b4faf6e975 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5939,8 +5939,8 @@ def warn_unavailable_fwdclass_message : Warning<
     "%0 may be unavailable because the receiver type is unknown">,
     InGroup<UnavailableDeclarations>;
 def note_availability_specified_here : Note<
-  "%0 has been explicitly marked "
-  "%select{unavailable|deleted|deprecated}1 here">;
+  "%select{|%1 }0has been explicitly marked "
+  
"%select{unavailable|deleted|deprecated|nodiscard|warn_unused_result|pure|const}2
 here">;
 def note_partial_availability_specified_here : Note<
   "%0 has been marked as being introduced in %1 %2 %select{|in %5 environment 
}4here, "
   "but the deployment target is %1 %3%select{| %6 environment }4">;
@@ -9263,7 +9263,7 @@ def warn_unused_container_subscript_expr : Warning<
  "container access result unused - container access should not be used for 
side effects">,
   InGroup<UnusedValue>;
 def warn_unused_call : Warning<
-  "ignoring return value of function declared with %0 attribute">,
+  "ignoring return value of function declared with %select{pure|const}0 
attribute">,
   InGroup<UnusedValue>;
 def warn_unused_constructor : Warning<
   "ignoring temporary created by a constructor declared with %0 attribute">,
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9ecbf121e3fc0d..6a3eb1238a89e2 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1616,22 +1616,23 @@ QualType CallExpr::getCallReturnType(const ASTContext 
&Ctx) const {
   return FnType->getReturnType();
 }
 
-const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const {
+std::pair<const Decl *, const Attr *>
+CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const {
   // If the return type is a struct, union, or enum that is marked nodiscard,
   // then return the return type attribute.
   if (const TagDecl *TD = getCallReturnType(Ctx)->getAsTagDecl())
     if (const auto *A = TD->getAttr<WarnUnusedResultAttr>())
-      return A;
+      return {TD, A};
 
   for (const auto *TD = getCallReturnType(Ctx)->getAs<TypedefType>(); TD;
        TD = TD->desugar()->getAs<TypedefType>())
     if (const auto *A = TD->getDecl()->getAttr<WarnUnusedResultAttr>())
-      return A;
+      return {TD->getDecl(), A};
 
   // Otherwise, see if the callee is marked nodiscard and return that attribute
   // instead.
   const Decl *D = getCalleeDecl();
-  return D ? D->getAttr<WarnUnusedResultAttr>() : nullptr;
+  return {D, D ? D->getAttr<WarnUnusedResultAttr>() : nullptr};
 }
 
 SourceLocation CallExpr::getBeginLoc() const {
diff --git a/clang/lib/Sema/SemaAvailability.cpp 
b/clang/lib/Sema/SemaAvailability.cpp
index 798cabaa31a476..da74033f233895 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -670,8 +670,12 @@ static void DoEmitAvailabilityWarning(Sema &S, 
AvailabilityResult K,
     S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
   }
 
-  S.Diag(NoteLocation, diag_available_here)
-    << OffendingDecl << available_here_select_kind;
+  if (diag_available_here == diag::note_availability_specified_here)
+    S.Diag(NoteLocation, diag_available_here)
+        << true << OffendingDecl << available_here_select_kind;
+  else
+    S.Diag(NoteLocation, diag_available_here)
+        << OffendingDecl << available_here_select_kind;
 }
 
 void Sema::handleDelayedAvailabilityCheck(DelayedDiagnostic &DD, Decl *Ctx) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 044f56f2af71bf..3951a40eecf5be 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -140,7 +140,7 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
     return NoteDeletedInheritingConstructor(Ctor);
 
   Diag(Decl->getLocation(), diag::note_availability_specified_here)
-    << Decl << 1;
+      << true << Decl << 1;
 }
 
 /// Determine whether a FunctionDecl was ever declared with an
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 9e235a46707cd4..873d6cf3a6bf45 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTLambda.h"
+#include "clang/AST/Attrs.inc"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
@@ -204,23 +205,30 @@ static bool DiagnoseUnusedComparison(Sema &S, const Expr 
*E) {
   return true;
 }
 
-static bool DiagnoseNoDiscard(Sema &S, const WarnUnusedResultAttr *A,
-                              SourceLocation Loc, SourceRange R1,
-                              SourceRange R2, bool IsCtor) {
+static bool DiagnoseNoDiscard(Sema &S, const Decl *OffendingDecl,
+                              const WarnUnusedResultAttr *A, SourceLocation 
Loc,
+                              SourceRange R1, SourceRange R2, bool IsCtor) {
   if (!A)
     return false;
   StringRef Msg = A->getMessage();
 
   if (Msg.empty()) {
     if (IsCtor)
-      return S.Diag(Loc, diag::warn_unused_constructor) << A << R1 << R2;
-    return S.Diag(Loc, diag::warn_unused_result) << A << R1 << R2;
+      S.Diag(Loc, diag::warn_unused_constructor) << A << R1 << R2;
+    else
+      S.Diag(Loc, diag::warn_unused_result) << A << R1 << R2;
+  } else if (IsCtor) {
+    S.Diag(Loc, diag::warn_unused_constructor_msg) << A << Msg << R1 << R2;
+  } else {
+    S.Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2;
   }
 
-  if (IsCtor)
-    return S.Diag(Loc, diag::warn_unused_constructor_msg) << A << Msg << R1
-                                                          << R2;
-  return S.Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2;
+  // nodiscard = 3, warn_unused_result = 4
+  unsigned available_here_select_kind =
+      (A->getSpelling() == StringRef{"nodiscard"} ? 3 : 4);
+  return S.Diag(A->getLocation(), diag::note_availability_specified_here)
+         << isa<NamedDecl>(OffendingDecl) << dyn_cast<NamedDecl>(OffendingDecl)
+         << available_here_select_kind;
 }
 
 void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {
@@ -290,9 +298,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, 
unsigned DiagID) {
     if (E->getType()->isVoidType())
       return;
 
-    if (DiagnoseNoDiscard(*this, cast_or_null<WarnUnusedResultAttr>(
-                                     CE->getUnusedResultAttr(Context)),
-                          Loc, R1, R2, /*isCtor=*/false))
+    const auto &[OffendingDecl, A] = CE->getUnusedResultAttr(Context);
+    if (DiagnoseNoDiscard(*this, OffendingDecl,
+                          cast_or_null<WarnUnusedResultAttr>(A), Loc, R1, R2,
+                          /*isCtor=*/false))
       return;
 
     // If the callee has attribute pure, const, or warn_unused_result, warn 
with
@@ -302,27 +311,47 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, 
unsigned DiagID) {
     if (const Decl *FD = CE->getCalleeDecl()) {
       if (ShouldSuppress)
         return;
-      if (FD->hasAttr<PureAttr>()) {
-        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
-        return;
-      }
-      if (FD->hasAttr<ConstAttr>()) {
-        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
+
+      const InheritableAttr *A = nullptr;
+      if (const auto *PA = FD->getAttr<PureAttr>())
+        A = PA;
+      else if (const auto *CA = FD->getAttr<ConstAttr>())
+        A = CA;
+
+      if (A) {
+        // pure = 0, const = 1 for warn_unused_call
+        unsigned available_here_select_kind = (isa<PureAttr>(A) ? 0 : 1);
+        Diag(Loc, diag::warn_unused_call)
+            << R1 << R2 << available_here_select_kind;
+        available_here_select_kind += 5; // pure = 5, const = 6 for 
availability
+        if (const auto *ND = dyn_cast<NamedDecl>(OffendingDecl)) {
+          if (!ND->getIdentifier()->getBuiltinID())
+            Diag(A->getLocation(), diag::note_availability_specified_here)
+                << true << ND << available_here_select_kind;
+        } else {
+          Diag(A->getLocation(), diag::note_availability_specified_here)
+              << false << ND << available_here_select_kind;
+        }
         return;
       }
     }
   } else if (const auto *CE = dyn_cast<CXXConstructExpr>(E)) {
     if (const CXXConstructorDecl *Ctor = CE->getConstructor()) {
+      const NamedDecl *OffendingDecl = Ctor;
       const auto *A = Ctor->getAttr<WarnUnusedResultAttr>();
-      A = A ? A : Ctor->getParent()->getAttr<WarnUnusedResultAttr>();
-      if (DiagnoseNoDiscard(*this, A, Loc, R1, R2, /*isCtor=*/true))
+      if (!A) {
+        OffendingDecl = Ctor->getParent();
+        A = OffendingDecl->getAttr<WarnUnusedResultAttr>();
+      }
+      if (DiagnoseNoDiscard(*this, OffendingDecl, A, Loc, R1, R2,
+                            /*isCtor=*/true))
         return;
     }
   } else if (const auto *ILE = dyn_cast<InitListExpr>(E)) {
     if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) {
 
-      if (DiagnoseNoDiscard(*this, TD->getAttr<WarnUnusedResultAttr>(), Loc, 
R1,
-                            R2, /*isCtor=*/false))
+      if (DiagnoseNoDiscard(*this, TD, TD->getAttr<WarnUnusedResultAttr>(), 
Loc,
+                            R1, R2, /*isCtor=*/false))
         return;
     }
   } else if (ShouldSuppress)
@@ -336,8 +365,8 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned 
DiagID) {
     }
     const ObjCMethodDecl *MD = ME->getMethodDecl();
     if (MD) {
-      if (DiagnoseNoDiscard(*this, MD->getAttr<WarnUnusedResultAttr>(), Loc, 
R1,
-                            R2, /*isCtor=*/false))
+      if (DiagnoseNoDiscard(*this, MD, MD->getAttr<WarnUnusedResultAttr>(), 
Loc,
+                            R1, R2, /*isCtor=*/false))
         return;
     }
   } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp 
b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
index 693ca29370cf3f..158fbdbd67be34 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
@@ -2,18 +2,18 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++17 
-verify=expected,cxx11-17,since-cxx17 -pedantic %s
 // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify=expected,since-cxx17 
-pedantic %s
 
-struct [[nodiscard]] S {};
+struct [[nodiscard]] S {}; // expected-note 4 {{'S' has been explicitly marked 
nodiscard here}}
 // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
 S get_s();
 S& get_s_ref();
 
-enum [[nodiscard]] E {};
+enum [[nodiscard]] E {}; // expected-note 2 {{'E' has been explicitly marked 
nodiscard here}}
 // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
 E get_e();
 
-[[nodiscard]] int get_i();
+[[nodiscard]] int get_i(); // expected-note {{'get_i' has been explicitly 
marked nodiscard here}}
 // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
-[[nodiscard]] volatile int &get_vi();
+[[nodiscard]] volatile int &get_vi(); // expected-note {{'get_vi' has been 
explicitly marked nodiscard here}}
 // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
 
 void f() {
@@ -32,6 +32,7 @@ void f() {
 
 [[nodiscard]] volatile char &(*fp)(); // expected-warning {{'nodiscard' 
attribute only applies to functions, classes, or enumerations}}
 // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
+// expected-note@-2 {{'fp' has been explicitly marked nodiscard here}}
 void g() {
   fp(); // expected-warning {{ignoring return value of function declared with 
'nodiscard' attribute}}
 
@@ -67,20 +68,20 @@ void f() {
 }
 } // namespace PR31526
 
-struct [[nodiscard("reason")]] ReasonStruct {};
+struct [[nodiscard("reason")]] ReasonStruct {}; // expected-note 
{{'ReasonStruct' has been explicitly marked nodiscard here}}
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 struct LaterReason;
-struct [[nodiscard("later reason")]] LaterReason {};
+struct [[nodiscard("later reason")]] LaterReason {}; // expected-note 
{{'LaterReason' has been explicitly marked nodiscard here}}
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 
 ReasonStruct get_reason();
 LaterReason get_later_reason();
-[[nodiscard("another reason")]] int another_reason();
+[[nodiscard("another reason")]] int another_reason(); // expected-note 
{{'another_reason' has been explicitly marked nodiscard here}}
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 
 [[nodiscard("conflicting reason")]] int conflicting_reason();
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
-[[nodiscard("special reason")]] int conflicting_reason();
+[[nodiscard("special reason")]] int conflicting_reason(); // expected-note 
{{'conflicting_reason' has been explicitly marked nodiscard here}}
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 
 void cxx20_use() {
@@ -91,23 +92,23 @@ void cxx20_use() {
 }
 
 namespace p1771 {
-struct[[nodiscard("Don't throw me away!")]] ConvertTo{};
+struct[[nodiscard("Don't throw me away!")]] ConvertTo{}; // expected-note 3 
{{'ConvertTo' has been explicitly marked nodiscard here}}
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 struct S {
-  [[nodiscard]] S();
+  [[nodiscard]] S(); // expected-note {{'S' has been explicitly marked 
nodiscard here}}
   // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
-  [[nodiscard("Don't let that S-Char go!")]] S(char);
+  [[nodiscard("Don't let that S-Char go!")]] S(char); // expected-note 2 {{'S' 
has been explicitly marked nodiscard here}}
   // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
   S(int);
   [[gnu::warn_unused_result]] S(double);
   operator ConvertTo();
-  [[nodiscard]] operator int();
+  [[nodiscard]] operator int(); // expected-note 2 {{'operator int' has been 
explicitly marked nodiscard here}}
   // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}}
-  [[nodiscard("Don't throw away as a double")]] operator double();
+  [[nodiscard("Don't throw away as a double")]] operator double(); // 
expected-note {{'operator double' has been explicitly marked nodiscard here}}
   // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 };
 
-struct[[nodiscard("Don't throw me away either!")]] Y{};
+struct[[nodiscard("Don't throw me away either!")]] Y{}; // expected-note {{'Y' 
has been explicitly marked nodiscard here}}
 // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 
extension}}
 
 void usage() {
diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp 
b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp
index a3543cff7d2c92..6df334e1c0b488 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -std=c++1z -verify %s
 
 namespace std_example {
-  struct [[nodiscard]] error_info{
+  struct [[nodiscard]] error_info{ // expected-note {{'error_info' has been 
explicitly marked nodiscard here}}
     // ...
   };
 
diff --git a/clang/test/OpenMP/declare_variant_messages.cpp 
b/clang/test/OpenMP/declare_variant_messages.cpp
index b8a806e7ef75b3..5fe53d70270fbc 100644
--- a/clang/test/OpenMP/declare_variant_messages.cpp
+++ b/clang/test/OpenMP/declare_variant_messages.cpp
@@ -133,7 +133,7 @@ int score_and_cond_const();
 template <int C>
 int score_and_cond_const_inst();
 
-__attribute__((pure)) int pure() { return 0; }
+__attribute__((pure)) int pure() { return 0; } // expected-note {{'pure' has 
been explicitly marked pure here}}
 
 #pragma omp declare variant(pure) match(user = {condition(1)}) // 
expected-warning {{ignoring return value of function declared with pure 
attribute}}
 int unused_warning_after_specialization() { return foo(); }
diff --git a/clang/test/Sema/c2x-nodiscard.c b/clang/test/Sema/c2x-nodiscard.c
index f8b0567366465d..8865e2f9cd0ca2 100644
--- a/clang/test/Sema/c2x-nodiscard.c
+++ b/clang/test/Sema/c2x-nodiscard.c
@@ -9,7 +9,7 @@ struct [[nodiscard]] S1 { // ok
 struct [[nodiscard, nodiscard]] S2 { // ok
   int i;
 };
-struct [[nodiscard("Wrong")]] S3 {
+struct [[nodiscard("Wrong")]] S3 { // expected-note {{'S3' has been explicitly 
marked nodiscard here}}
   int i;
 };
 
@@ -20,15 +20,15 @@ enum [[nodiscard]] E1 { One };
 
 [[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies 
to Objective-C methods, enums, structs, unions, classes, functions, function 
pointers, and typedefs}}
 
-struct [[nodiscard]] S4 {
+struct [[nodiscard]] S4 { // expected-note {{'S4' has been explicitly marked 
nodiscard here}}
   int i;
 };
 struct S4 get_s(void);
 
-enum [[nodiscard]] E2 { Two };
+enum [[nodiscard]] E2 { Two }; // expected-note {{'E2' has been explicitly 
marked nodiscard here}}
 enum E2 get_e(void);
 
-[[nodiscard]] int get_i(void);
+[[nodiscard]] int get_i(void); // expected-note {{'get_i' has been explicitly 
marked nodiscard here}}
 
 void f2(void) {
   get_s(); // expected-warning {{ignoring return value of function declared 
with 'nodiscard' attribute}}
@@ -43,7 +43,7 @@ void f2(void) {
   (void)get_e();
 }
 
-struct [[nodiscard]] error_info{
+struct [[nodiscard]] error_info{ // expected-note {{'error_info' has been 
explicitly marked nodiscard here}}
   int i;
 };
 
@@ -54,7 +54,7 @@ void test_missiles(void) {
   launch_missiles();
 }
 
-[[nodiscard]] int f3();
+[[nodiscard]] int f3(); // expected-note {{'f3' has been explicitly marked 
nodiscard here}}
 
 void GH104391() {
 #define M (unsigned int) f3()
diff --git a/clang/test/Sema/unused-expr.c b/clang/test/Sema/unused-expr.c
index 6723a33cbd4e01..9e444f94d67137 100644
--- a/clang/test/Sema/unused-expr.c
+++ b/clang/test/Sema/unused-expr.c
@@ -73,15 +73,15 @@ void t4(int a) {
   for (;;b < 1) {} // expected-warning{{relational comparison result unused}}
 }
 
-int t5f(void) __attribute__((warn_unused_result));
+int t5f(void) __attribute__((warn_unused_result)); // expected-note {{'t5f' 
has been explicitly marked warn_unused_result here}}
 void t5(void) {
   t5f();   // expected-warning {{ignoring return value of function declared 
with 'warn_unused_result' attribute}}
 }
 
 
-int fn1(void) __attribute__ ((warn_unused_result));
-int fn2() __attribute__ ((pure));
-int fn3() __attribute__ ((__const));
+int fn1(void) __attribute__ ((warn_unused_result)); // expected-note 3 {{'fn1' 
has been explicitly marked warn_unused_result here}}
+int fn2() __attribute__ ((pure)); // expected-note 2 {{'fn2' has been 
explicitly marked pure here}}
+int fn3() __attribute__ ((__const)); // expected-note {{'fn3' has been 
explicitly marked const here}}
 int t6(void) {
   if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0)  // no warnings
     return -1;
@@ -97,7 +97,7 @@ int t6(void) {
 int t7 __attribute__ ((warn_unused_result)); // expected-warning 
{{'warn_unused_result' attribute only applies to Objective-C methods, enums, 
structs, unions, classes, functions, function pointers, and typedefs}}
 
 // PR4010
-int (*fn4)(void) __attribute__ ((warn_unused_result));
+int (*fn4)(void) __attribute__ ((warn_unused_result)); // expected-note 
{{'fn4' has been explicitly marked warn_unused_result here}}
 void t8(void) {
   fn4(); // expected-warning {{ignoring return value of function declared with 
'warn_unused_result' attribute}}
 }
diff --git a/clang/test/SemaCXX/coroutines.cpp 
b/clang/test/SemaCXX/coroutines.cpp
index 068fdab4bfe384..c9d442a0338121 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -1497,7 +1497,7 @@ class awaitable_unused_warn {
   using handle_type = std::coroutine_handle<>;
   constexpr bool await_ready() noexcept { return false; }
   void await_suspend(handle_type) noexcept {}
-  [[nodiscard]] int await_resume() noexcept { return 1; }
+  [[nodiscard]] int await_resume() noexcept { return 1; } // expected-note 2 
{{'await_resume' has been explicitly marked nodiscard here}}
 };
 
 template <class Await>
diff --git a/clang/test/SemaCXX/warn-unused-result.cpp 
b/clang/test/SemaCXX/warn-unused-result.cpp
index 4b7a2503ecc0dd..247be530274af2 100644
--- a/clang/test/SemaCXX/warn-unused-result.cpp
+++ b/clang/test/SemaCXX/warn-unused-result.cpp
@@ -1,13 +1,13 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
-int f() __attribute__((warn_unused_result));
+int f() __attribute__((warn_unused_result)); // expected-note 12 {{'f' has 
been explicitly marked warn_unused_result here}}
 
 struct S {
   void t() const;
 };
-S g1() __attribute__((warn_unused_result));
-S *g2() __attribute__((warn_unused_result));
-S &g3() __attribute__((warn_unused_result));
+S g1() __attribute__((warn_unused_result)); // expected-note {{'g1' has been 
explicitly marked warn_unused_result here}}
+S *g2() __attribute__((warn_unused_result)); // expected-note {{'g2' has been 
explicitly marked warn_unused_result here}}
+S &g3() __attribute__((warn_unused_result)); // expected-note {{'g3' has been 
explicitly marked warn_unused_result here}}
 
 void test() {
   f(); // expected-warning {{ignoring return value}}
@@ -64,7 +64,7 @@ void testSubstmts(int i) {
 }
 
 struct X {
- int foo() __attribute__((warn_unused_result));
+ int foo() __attribute__((warn_unused_result)); // expected-note 2 {{'foo' has 
been explicitly marked warn_unused_result here}}
 };
 
 void bah() {
@@ -80,7 +80,7 @@ class Foo {
   Status doStuff();
 };
 
-struct [[clang::warn_unused_result]] Status {
+struct [[clang::warn_unused_result]] Status { // expected-note 3 {{'Status' 
has been explicitly marked warn_unused_result here}}
   bool ok() const;
   Status& operator=(const Status& x);
   inline void Update(const Status& new_status) {
@@ -115,7 +115,7 @@ void lazy() {
 }
 
 template <typename T>
-class [[clang::warn_unused_result]] StatusOr {
+class [[clang::warn_unused_result]] StatusOr { // expected-note 
{{'StatusOr<int>' has been explicitly marked warn_unused_result here}}
 };
 StatusOr<int> doit();
 void test() {
@@ -129,7 +129,7 @@ void test() {
 }
 
 namespace PR17587 {
-struct [[clang::warn_unused_result]] Status;
+struct [[clang::warn_unused_result]] Status; // expected-note {{'Status' has 
been explicitly marked warn_unused_result here}}
 
 struct Foo {
   Status Bar();
@@ -193,7 +193,7 @@ void g() {
 
 namespace {
 // C++ Methods should warn even in their own class.
-struct [[clang::warn_unused_result]] S {
+struct [[clang::warn_unused_result]] S { // expected-note 5 {{'S' has been 
explicitly marked warn_unused_result here}}
   S DoThing() { return {}; };
   S operator++(int) { return {}; };
   S operator--(int) { return {}; };
@@ -202,7 +202,7 @@ struct [[clang::warn_unused_result]] S {
   S operator--() { return {}; };
 };
 
-struct [[clang::warn_unused_result]] P {
+struct [[clang::warn_unused_result]] P { // expected-note 5 {{'P' has been 
explicitly marked warn_unused_result here}}
   P DoThing() { return {}; };
 };
 
@@ -238,7 +238,7 @@ void f() {
 } // namespace
 
 namespace PR39837 {
-[[clang::warn_unused_result]] int f(int);
+[[clang::warn_unused_result]] int f(int); // expected-note {{'f' has been 
explicitly marked warn_unused_result here}}
 
 void g() {
   int a[2];
@@ -256,7 +256,7 @@ void i([[nodiscard]] bool (*fp)()); // expected-warning 
{{'nodiscard' attribute
 }
 
 namespace unused_typedef_result {
-[[clang::warn_unused_result]] typedef void *a;
+[[clang::warn_unused_result]] typedef void *a; // expected-note 3 {{'a' has 
been explicitly marked warn_unused_result here}}
 typedef a indirect;
 a af1();
 indirect indirectf1();
@@ -276,7 +276,7 @@ void bf2() {
   b1f1(); // no warning
   b2f1(); // no warning
 }
-__attribute__((warn_unused_result)) typedef void *c;
+__attribute__((warn_unused_result)) typedef void *c; // expected-note 2 {{'c' 
has been explicitly marked warn_unused_result here}}
 c cf1();
 void cf2() {
   cf1(); // expected-warning {{ignoring return value}}
diff --git a/clang/test/SemaObjC/method-warn-unused-attribute.m 
b/clang/test/SemaObjC/method-warn-unused-attribute.m
index b83dabf3bbdc22..99917b8df94330 100644
--- a/clang/test/SemaObjC/method-warn-unused-attribute.m
+++ b/clang/test/SemaObjC/method-warn-unused-attribute.m
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1  -fsyntax-only -Wunused-value -verify %s
 
 @interface INTF
-- (id) foo __attribute__((warn_unused_result)); 
+- (id) foo __attribute__((warn_unused_result));
 - (void) garf __attribute__((warn_unused_result)); // expected-warning 
{{attribute 'warn_unused_result' cannot be applied to Objective-C method 
without return value}}
-- (int) fee __attribute__((warn_unused_result));
-+ (int) c __attribute__((warn_unused_result));
+- (int) fee __attribute__((warn_unused_result)); // expected-note {{'fee' has 
been explicitly marked warn_unused_result here}}
++ (int) c __attribute__((warn_unused_result)); // expected-note {{'c' has been 
explicitly marked warn_unused_result here}}
 @end
 
 void foo(INTF *a) {

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to