diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 2a3950b2fc598a..53f6e78cdfcb6b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -672,6 +672,7 @@ Improvements to Clang's diagnostics getS(); // Now diagnoses "Reason 2", previously diagnoses "Reason 1" } +- Clang now diagnoses ``= delete("reason")`` extension warnings only in pedantic mode rather than on by default. (#GH109311). - Clang now diagnoses missing return value in functions containing ``if consteval`` (#GH116485). diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 708c8656decbe0..466c65a9685ad3 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3181,14 +3181,12 @@ class CallExpr : public Expr { QualType getCallReturnType(const ASTContext &Ctx) const; /// Returns the WarnUnusedResultAttr that is either declared on the called - /// function, or its return type declaration, together with a NamedDecl that - /// refers to the declaration the attribute is attached onto. - std::pair - getUnusedResultAttr(const ASTContext &Ctx) const; + /// function, or its return type declaration. + 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).second != nullptr; + return getUnusedResultAttr(Ctx) != nullptr; } SourceLocation getRParenLoc() const { return RParenLoc; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e429538114dd6e..6edfb562a815bf 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9307,11 +9307,11 @@ def warn_unused_container_subscript_expr : Warning< def warn_unused_call : Warning< "ignoring return value of function declared with %0 attribute">, InGroup; -def warn_unused_return_type : Warning< - "ignoring %select{return value|temporary}0 of type %2 declared with %1 attribute%select{|: %4}3">, - InGroup; def warn_unused_constructor : Warning< - "ignoring temporary created by a constructor declared with %0 attribute%select{|: %2}1">, + "ignoring temporary created by a constructor declared with %0 attribute">, + InGroup; +def warn_unused_constructor_msg : Warning< + "ignoring temporary created by a constructor declared with %0 attribute: %1">, InGroup; def warn_side_effects_unevaluated_context : Warning< "expression with side effects has no effect in an unevaluated context">, @@ -9320,7 +9320,10 @@ def warn_side_effects_typeid : Warning< "expression with side effects will be evaluated despite being used as an " "operand to 'typeid'">, InGroup; def warn_unused_result : Warning< - "ignoring return value of function declared with %0 attribute%select{|: %2}1">, + "ignoring return value of function declared with %0 attribute">, + InGroup; +def warn_unused_result_msg : Warning< + "ignoring return value of function declared with %0 attribute: %1">, InGroup; def warn_unused_result_typedef_unsupported_spelling : Warning< "'[[%select{nodiscard|gnu::warn_unused_result}0]]' attribute ignored when " diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 5a6738196d2890..b4b921518800f9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1615,24 +1615,22 @@ QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const { return FnType->getReturnType(); } -std::pair -CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const { - // If the callee is marked nodiscard, return that attribute - const Decl *D = getCalleeDecl(); - if (const auto *A = D->getAttr()) - return {nullptr, A}; - +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()) - return {TD, A}; + return A; for (const auto *TD = getCallReturnType(Ctx)->getAs(); TD; TD = TD->desugar()->getAs()) if (const auto *A = TD->getDecl()->getAttr()) - return {TD->getDecl(), A}; - return {nullptr, nullptr}; + return A; + + // Otherwise, see if the callee is marked nodiscard and return that attribute + // instead. + const Decl *D = getCalleeDecl(); + return D ? D->getAttr() : nullptr; } SourceLocation CallExpr::getBeginLoc() const { diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 0e5c6cd49dccad..c7502fc52f54f7 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -200,30 +200,23 @@ static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) { return true; } -static bool DiagnoseNoDiscard(Sema &S, const NamedDecl *OffendingDecl, - const WarnUnusedResultAttr *A, SourceLocation Loc, - SourceRange R1, SourceRange R2, bool IsCtor) { +static bool DiagnoseNoDiscard(Sema &S, const WarnUnusedResultAttr *A, + SourceLocation Loc, SourceRange R1, + SourceRange R2, bool IsCtor) { if (!A) return false; StringRef Msg = A->getMessage(); if (Msg.empty()) { - if (OffendingDecl) - return S.Diag(Loc, diag::warn_unused_return_type) - << IsCtor << A << OffendingDecl << false << R1 << R2; if (IsCtor) - return S.Diag(Loc, diag::warn_unused_constructor) - << A << false << R1 << R2; - return S.Diag(Loc, diag::warn_unused_result) << A << false << R1 << R2; + return S.Diag(Loc, diag::warn_unused_constructor) << A << R1 << R2; + return S.Diag(Loc, diag::warn_unused_result) << A << R1 << R2; } - if (OffendingDecl) - return S.Diag(Loc, diag::warn_unused_return_type) - << IsCtor << A << OffendingDecl << true << Msg << R1 << R2; if (IsCtor) - return S.Diag(Loc, diag::warn_unused_constructor) - << A << true << Msg << R1 << R2; - return S.Diag(Loc, diag::warn_unused_result) << A << true << Msg << R1 << R2; + 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; } void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) { @@ -293,10 +286,9 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) { if (E->getType()->isVoidType()) return; - auto [OffendingDecl, A] = CE->getUnusedResultAttr(Context); - if (DiagnoseNoDiscard(*this, OffendingDecl, - cast_or_null(A), Loc, R1, R2, - /*isCtor=*/false)) + if (DiagnoseNoDiscard(*this, cast_or_null( + CE->getUnusedResultAttr(Context)), + Loc, R1, R2, /*isCtor=*/false)) return; // If the callee has attribute pure, const, or warn_unused_result, warn with @@ -317,21 +309,16 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) { } } else if (const auto *CE = dyn_cast(E)) { if (const CXXConstructorDecl *Ctor = CE->getConstructor()) { - const NamedDecl *OffendingDecl = nullptr; const auto *A = Ctor->getAttr(); - if (!A) { - OffendingDecl = Ctor->getParent(); - A = OffendingDecl->getAttr(); - } - if (DiagnoseNoDiscard(*this, OffendingDecl, A, Loc, R1, R2, - /*isCtor=*/true)) + A = A ? A : Ctor->getParent()->getAttr(); + if (DiagnoseNoDiscard(*this, A, Loc, R1, R2, /*isCtor=*/true)) return; } } else if (const auto *ILE = dyn_cast(E)) { if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) { - if (DiagnoseNoDiscard(*this, TD, TD->getAttr(), Loc, - R1, R2, /*isCtor=*/false)) + if (DiagnoseNoDiscard(*this, TD->getAttr(), Loc, R1, + R2, /*isCtor=*/false)) return; } } else if (ShouldSuppress) @@ -345,8 +332,8 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) { } const ObjCMethodDecl *MD = ME->getMethodDecl(); if (MD) { - if (DiagnoseNoDiscard(*this, nullptr, MD->getAttr(), - Loc, R1, R2, /*isCtor=*/false)) + if (DiagnoseNoDiscard(*this, MD->getAttr(), Loc, R1, + R2, /*isCtor=*/false)) return; } } else if (const PseudoObjectExpr *POE = dyn_cast(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 da1f8201f55dcc..693ca29370cf3f 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 @@ -17,10 +17,10 @@ E get_e(); // cxx11-warning@-1 {{use of the 'nodiscard' attribute is a C++17 extension}} void f() { - get_s(); // expected-warning {{ignoring return value of type 'S' declared with 'nodiscard' attribute}} + get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} get_vi(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - get_e(); // expected-warning {{ignoring return value of type 'E' declared with 'nodiscard' attribute}} + get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} // Okay, warnings are not encouraged get_s_ref(); @@ -54,10 +54,10 @@ void f() { fp3 three; fp2_alias four; - one(); // expected-warning {{ignoring return value of type 'E' declared with 'nodiscard' attribute}} - two(); // expected-warning {{ignoring return value of type 'S' declared with 'nodiscard' attribute}} - three(); // expected-warning {{ignoring return value of type 'S' declared with 'nodiscard' attribute}} - four(); // expected-warning {{ignoring return value of type 'S' declared with 'nodiscard' attribute}} + one(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + two(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + three(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + four(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} // These are all okay because of the explicit cast to void. (void)one(); @@ -84,8 +84,8 @@ LaterReason get_later_reason(); // cxx11-17-warning@-1 {{use of the 'nodiscard' attribute is a C++20 extension}} void cxx20_use() { - get_reason(); // expected-warning {{ignoring return value of type 'ReasonStruct' declared with 'nodiscard' attribute: reason}} - get_later_reason(); // expected-warning {{ignoring return value of type 'LaterReason' declared with 'nodiscard' attribute: later reason}} + get_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: reason}} + get_later_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: later reason}} another_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: another reason}} conflicting_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: special reason}} } @@ -115,20 +115,20 @@ void usage() { 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); - Y(); // expected-warning {{ignoring temporary of type 'Y' declared with 'nodiscard' attribute: Don't throw me away either!}} + Y(); // expected-warning {{ignoring temporary created by a constructor 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!}} + ConvertTo{}; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}} // AST is different in C++17 mode. Before, a move ctor for ConvertTo is there // as well, hence the constructor warning. - // since-cxx17-warning@+2 {{ignoring return value of type 'ConvertTo' declared with 'nodiscard' attribute: Don't throw me away!}} - // cxx11-warning@+1 {{ignoring temporary of type 'ConvertTo' declared with 'nodiscard' attribute: Don't throw me away!}} + // since-cxx17-warning@+2 {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}} + // cxx11-warning@+1 {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away!}} (ConvertTo) s; (int)s; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} (S)'c'; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't let that S-Char go!}} - // since-cxx17-warning@+2 {{ignoring return value of type 'ConvertTo' declared with 'nodiscard' attribute: Don't throw me away!}} - // cxx11-warning@+1 {{ignoring temporary of type 'ConvertTo' declared with 'nodiscard' attribute: Don't throw me away!}} + // since-cxx17-warning@+2 {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}} + // cxx11-warning@+1 {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away!}} static_cast(s); static_cast(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} static_cast(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw away as a double}} 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 b37517921b1ca4..a3543cff7d2c92 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 @@ -8,7 +8,7 @@ namespace std_example { error_info enable_missile_safety_mode(); void launch_missiles(); void test_missiles() { - enable_missile_safety_mode(); // expected-warning {{ignoring return value of type 'error_info' declared with 'nodiscard'}} + enable_missile_safety_mode(); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} launch_missiles(); } diff --git a/clang/test/Sema/c2x-nodiscard.c b/clang/test/Sema/c2x-nodiscard.c index e2537bcf1d29d6..f8b0567366465d 100644 --- a/clang/test/Sema/c2x-nodiscard.c +++ b/clang/test/Sema/c2x-nodiscard.c @@ -31,10 +31,10 @@ enum E2 get_e(void); [[nodiscard]] int get_i(void); void f2(void) { - get_s(); // expected-warning {{ignoring return value of type 'S4' declared with 'nodiscard' attribute}} - get_s3(); // expected-warning {{ignoring return value of type 'S3' declared with 'nodiscard' attribute: Wrong}} + get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + get_s3(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Wrong}} get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - get_e(); // expected-warning {{ignoring return value of type 'E2' declared with 'nodiscard' attribute}} + get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} // Okay, warnings are not encouraged (void)get_s(); @@ -50,7 +50,7 @@ struct [[nodiscard]] error_info{ struct error_info enable_missile_safety_mode(void); void launch_missiles(void); void test_missiles(void) { - enable_missile_safety_mode(); // expected-warning {{ignoring return value of type 'error_info' declared with 'nodiscard'}} + enable_missile_safety_mode(); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} launch_missiles(); } diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp index 682c500dc1d96d..4b7a2503ecc0dd 100644 --- a/clang/test/SemaCXX/warn-unused-result.cpp +++ b/clang/test/SemaCXX/warn-unused-result.cpp @@ -108,7 +108,7 @@ void lazy() { (void)DoAnotherThing(); (void)DoYetAnotherThing(); - DoSomething(); // expected-warning {{ignoring return value of type 'Status' declared with 'warn_unused_result'}} + DoSomething(); // expected-warning {{ignoring return value}} DoSomethingElse(); DoAnotherThing(); DoYetAnotherThing(); @@ -120,11 +120,11 @@ class [[clang::warn_unused_result]] StatusOr { StatusOr doit(); void test() { Foo f; - f.doStuff(); // expected-warning {{ignoring return value of type 'Status' declared with 'warn_unused_result'}} - doit(); // expected-warning {{ignoring return value of type 'StatusOr' declared with 'warn_unused_result'}} + f.doStuff(); // expected-warning {{ignoring return value}} + doit(); // expected-warning {{ignoring return value}} auto func = []() { return Status(); }; - func(); // expected-warning {{ignoring return value of type 'Status' declared with 'warn_unused_result'}} + func(); // expected-warning {{ignoring return value}} } } @@ -139,7 +139,7 @@ struct Status {}; void Bar() { Foo f; - f.Bar(); // expected-warning {{ignoring return value of type 'Status' declared with 'warn_unused_result'}} + f.Bar(); // expected-warning {{ignoring return value}} }; } @@ -215,18 +215,18 @@ P operator--(const P &) { return {}; }; void f() { S s; P p; - s.DoThing(); // expected-warning {{ignoring return value of type 'S' declared with 'warn_unused_result'}} - p.DoThing(); // expected-warning {{ignoring return value of type 'P' declared with 'warn_unused_result'}} + s.DoThing(); // expected-warning {{ignoring return value}} + p.DoThing(); // expected-warning {{ignoring return value}} // Only postfix is expected to warn when written correctly. - s++; // expected-warning {{ignoring return value of type 'S' declared with 'warn_unused_result'}} - s--; // expected-warning {{ignoring return value of type 'S' declared with 'warn_unused_result'}} - p++; // expected-warning {{ignoring return value of type 'P' declared with 'warn_unused_result'}} - p--; // expected-warning {{ignoring return value of type 'P' declared with 'warn_unused_result'}} + s++; // expected-warning {{ignoring return value}} + s--; // expected-warning {{ignoring return value}} + p++; // expected-warning {{ignoring return value}} + p--; // expected-warning {{ignoring return value}} // Improperly written prefix operators should still warn. - ++s; // expected-warning {{ignoring return value of type 'S' declared with 'warn_unused_result'}} - --s; // expected-warning {{ignoring return value of type 'S' declared with 'warn_unused_result'}} - ++p; // expected-warning {{ignoring return value of type 'P' declared with 'warn_unused_result'}} - --p; // expected-warning {{ignoring return value of type 'P' declared with 'warn_unused_result'}} + ++s; // expected-warning {{ignoring return value}} + --s; // expected-warning {{ignoring return value}} + ++p; // expected-warning {{ignoring return value}} + --p; // expected-warning {{ignoring return value}} // Silencing the warning by cast to void still works. (void)s.DoThing(); @@ -243,7 +243,7 @@ namespace PR39837 { void g() { int a[2]; for (int b : a) - f(b); // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}} + f(b); // expected-warning {{ignoring return value}} } } // namespace PR39837 @@ -261,12 +261,12 @@ typedef a indirect; a af1(); indirect indirectf1(); void af2() { - af1(); // expected-warning {{ignoring return value of type 'a' declared with 'warn_unused_result'}} + af1(); // expected-warning {{ignoring return value}} void *(*a1)(); a1(); // no warning a (*a2)(); - a2(); // expected-warning {{ignoring return value of type 'a' declared with 'warn_unused_result'}} - indirectf1(); // expected-warning {{ignoring return value of type 'a' declared with 'warn_unused_result'}} + a2(); // expected-warning {{ignoring return value}} + indirectf1(); // expected-warning {{ignoring return value}} } [[nodiscard]] typedef void *b1; // expected-warning {{'[[nodiscard]]' attribute ignored when applied to a typedef; consider using '__attribute__((warn_unused_result))' or '[[clang::warn_unused_result]]' instead}} [[gnu::warn_unused_result]] typedef void *b2; // expected-warning {{'[[gnu::warn_unused_result]]' attribute ignored when applied to a typedef; consider using '__attribute__((warn_unused_result))' or '[[clang::warn_unused_result]]' instead}} @@ -279,79 +279,10 @@ void bf2() { __attribute__((warn_unused_result)) typedef void *c; c cf1(); void cf2() { - cf1(); // expected-warning {{ignoring return value of type 'c' declared with 'warn_unused_result'}} + cf1(); // expected-warning {{ignoring return value}} void *(*c1)(); c1(); c (*c2)(); - c2(); // expected-warning {{ignoring return value of type 'c' declared with 'warn_unused_result'}} + c2(); // expected-warning {{ignoring return value}} } } - -namespace nodiscard_specialization { -// Test to only mark a specialization of class template as nodiscard -template struct S { S(int) {} }; -template<> struct [[nodiscard]] S { S(int) {} }; -template struct [[clang::warn_unused_result]] S { S(int) {} }; - -template -S obtain(const T&) { return {2}; } - -template -[[nodiscard]] S obtain2(const T&) { return {2}; } - -template -__attribute__((warn_unused_result)) S obtain3(const T&) { return {2}; } - -void use() { - obtain(1.0); // no warning - obtain(1); // expected-warning {{ignoring return value of type 'S' declared with 'nodiscard'}} - obtain(1); // expected-warning {{ignoring return value of type 'S' declared with 'warn_unused_result'}} - - S(2); // no warning - S(2); // expected-warning {{ignoring temporary of type 'S' declared with 'nodiscard'}} - S(2); // no warning (warn_unused_result does not diagnose constructor temporaries) - - // function should take precedence over type - obtain2(1.0); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} - obtain2(1); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} - obtain2(1); // expected-warning {{ignoring return value of function declared with 'nodiscard'}} - obtain3(1.0); // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}} - obtain3(1); // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}} - obtain3(1); // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}} -} - -// Test on constructor nodiscard -struct H { - explicit H(int) {} - [[nodiscard]] explicit H(double) {} - __attribute__((warn_unused_result)) H(const char*) {} -}; - -struct [[nodiscard]] G { - explicit G(int) {} - [[nodiscard]] explicit G(double) {} - [[clang::warn_unused_result]] G(const char*) {} -}; - -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) - - // no warning for explicit cast to void - (void)H(2); - (void)H{2.0}; - (void)H{"Hello"}; - - // warns for all these invocations - // here, constructor/function should take precedence over type - G{2}; // expected-warning {{ignoring temporary of type 'G' declared with 'nodiscard'}} - G(2.0); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard'}} - G("Hello"); // expected-warning {{ignoring temporary created by a constructor declared with 'warn_unused_result'}} - - // no warning for explicit cast to void - (void)G(2); - (void)G{2.0}; - (void)G{"Hello"}; -} -} // namespace nodiscard_specialization diff --git a/revert_patches.txt b/revert_patches.txt index b7b0e4a3271b5e..9c149f8be8ca42 100644 --- a/revert_patches.txt +++ b/revert_patches.txt @@ -13,6 +13,10 @@ breaks devicelibs 6e0b0038 [clang][OpenCL][CodeGen][AMDGPU] Do not use `private` as the default AS for when `generic` is available (#112442) AlexV and MarkS --- +breaks build of hipRuntime +51ad2901ca54 [Clang] Improve diagnostic on `[[nodiscard]]` attribute (#112521) +Ron, Maneesh +--- Revert: breaks build of rocFFT 854d7301f989 [Clang/AMDGPU] Zero sized arrays not allowed in HIP device code. (#113470) Ron and Vigneshwar