https://github.com/halbi2 updated https://github.com/llvm/llvm-project/pull/153116
>From ca3213a6e252919fe6eb19ed2a6d6cd6de539bca Mon Sep 17 00:00:00 2001 From: halbi2 <hehira...@gmail.com> Date: Mon, 11 Aug 2025 21:29:46 -0400 Subject: [PATCH 1/2] [clang] [Sema] Simplify Expr::isUnusedResultAWarning for CXXConstructExpr Two tests have new warnings because `warn_unused_result` is now respected for constructor temporaries. These tests were newly added in #112521 last year. This is good because the new behavior is better than the old. --- clang/lib/AST/Expr.cpp | 33 ++++++------------- .../dcl.attr/dcl.attr.nodiscard/p2.cpp | 2 +- clang/test/SemaCXX/warn-unused-result.cpp | 4 +-- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7cac655ef151c..e3a746069cd3f 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2805,32 +2805,19 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, case CXXTemporaryObjectExprClass: case CXXConstructExprClass: { - if (const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl()) { - const auto *WarnURAttr = Type->getAttr<WarnUnusedResultAttr>(); - if (Type->hasAttr<WarnUnusedAttr>() || - (WarnURAttr && WarnURAttr->IsCXX11NoDiscard())) { - WarnE = this; - Loc = getBeginLoc(); - R1 = getSourceRange(); - return true; - } - } - const auto *CE = cast<CXXConstructExpr>(this); - if (const CXXConstructorDecl *Ctor = CE->getConstructor()) { - const auto *WarnURAttr = Ctor->getAttr<WarnUnusedResultAttr>(); - if (WarnURAttr && WarnURAttr->IsCXX11NoDiscard()) { - WarnE = this; - Loc = getBeginLoc(); - R1 = getSourceRange(); + const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl(); - if (unsigned NumArgs = CE->getNumArgs()) - R2 = SourceRange(CE->getArg(0)->getBeginLoc(), - CE->getArg(NumArgs - 1)->getEndLoc()); - return true; - } - } + if ((Type && Type->hasAttr<WarnUnusedAttr>()) || CE->hasUnusedResultAttr(Ctx)) { + WarnE = this; + Loc = getBeginLoc(); + R1 = getSourceRange(); + if (unsigned NumArgs = CE->getNumArgs()) + R2 = SourceRange(CE->getArg(0)->getBeginLoc(), + CE->getArg(NumArgs - 1)->getEndLoc()); + return true; + } return false; } 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 0012ab976baa5..7f933a4dcc6b2 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 @@ -115,7 +115,7 @@ void usage() { S(); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}} S('A'); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't let that S-Char go!}} S(1); - S(2.2); + S(2.2); // expected-warning {{ignoring temporary created by a constructor declared with 'gnu::warn_unused_result' attribute}} Y(); // expected-warning {{ignoring temporary of type 'Y' declared with 'nodiscard' attribute: Don't throw me away either!}} S s; ConvertTo{}; // expected-warning {{ignoring return value of type 'ConvertTo' declared with 'nodiscard' attribute: Don't throw me away!}} diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp index 447654eccd563..1f7913f1aa994 100644 --- a/clang/test/SemaCXX/warn-unused-result.cpp +++ b/clang/test/SemaCXX/warn-unused-result.cpp @@ -309,7 +309,7 @@ void use() { S<double>(2); // no warning S<int>(2); // expected-warning {{ignoring temporary of type 'S<int>' declared with 'nodiscard'}} - S<const char>(2); // no warning (warn_unused_result does not diagnose constructor temporaries) + S<const char>(2); // expected-warning {{ignoring temporary of type 'S<const char>' declared with 'clang::warn_unused_result' attribute}} // function should take precedence over type obtain2(1.0); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} @@ -336,7 +336,7 @@ struct [[nodiscard]] G { void use2() { H{2}; // no warning H(2.0); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard'}} - H("Hello"); // no warning (warn_unused_result does not diagnose constructor temporaries) + H("Hello"); // expected-warning {{ignoring temporary created by a constructor declared with 'warn_unused_result' attribute}} // no warning for explicit cast to void (void)H(2); >From 426d6d765a59c5a4dc356848b8a3b1db23a2d3c1 Mon Sep 17 00:00:00 2001 From: halbi2 <hehira...@gmail.com> Date: Mon, 11 Aug 2025 23:14:35 -0400 Subject: [PATCH 2/2] fix clang-format --- clang/lib/AST/Expr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index e3a746069cd3f..e14cff552c922 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2808,7 +2808,8 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, const auto *CE = cast<CXXConstructExpr>(this); const CXXRecordDecl *Type = getType()->getAsCXXRecordDecl(); - if ((Type && Type->hasAttr<WarnUnusedAttr>()) || CE->hasUnusedResultAttr(Ctx)) { + if ((Type && Type->hasAttr<WarnUnusedAttr>()) || + CE->hasUnusedResultAttr(Ctx)) { WarnE = this; Loc = getBeginLoc(); R1 = getSourceRange(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits