Author: zebullax Date: 2025-07-14T09:54:24-04:00 New Revision: e35b01da11ade0f89c0dafb8e723af3ae8be5c01
URL: https://github.com/llvm/llvm-project/commit/e35b01da11ade0f89c0dafb8e723af3ae8be5c01 DIFF: https://github.com/llvm/llvm-project/commit/e35b01da11ade0f89c0dafb8e723af3ae8be5c01.diff LOG: [clang] Build argument string for clang::warn_unused_result (#148090) Preserve the argument-clause for `warn-unused-result` when under clang:: scope. We are not touching gnu:: scope for now as it's an error for GCC to have that string. Personally I think it would be ok to relax it here too as we are not introducing breakage to currently passing code, but feedback is to go slowly about it. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaDeclAttr.cpp clang/test/SemaCXX/warn-unused-result.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9f745e8e0dca3..970825c98fec1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -475,6 +475,9 @@ related warnings within the method body. - Clang now disallows the use of attributes applied before an ``extern template`` declaration (#GH79893). +- Clang will print the "reason" string argument passed on to + ``[[clang::warn_unused_result("reason")]]`` as part of the warning diagnostic. + Improvements to Clang's diagnostics ----------------------------------- diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 60a9aee2d41e7..5f481ed1f7139 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2902,28 +2902,37 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) { } StringRef Str; - if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) { - // The standard attribute cannot be applied to variable declarations such - // as a function pointer. - if (isa<VarDecl>(D)) - S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) - << AL << AL.isRegularKeywordAttribute() - << ExpectedFunctionOrClassOrEnum; - - // If this is spelled as the standard C++17 attribute, but not in C++17, - // warn about using it as an extension. If there are attribute arguments, - // then claim it's a C++20 extension instead. C23 supports this attribute - // with the message; no extension warning is needed there beyond the one - // already issued for accepting attributes in older modes. - const LangOptions &LO = S.getLangOpts(); - if (AL.getNumArgs() == 1) { - if (LO.CPlusPlus && !LO.CPlusPlus20) - S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL; - - if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr)) + if (AL.isStandardAttributeSyntax()) { + // If this is spelled [[clang::warn_unused_result]] we look for an optional + // string literal. This is not gated behind any specific version of the + // standard. + if (AL.isClangScope()) { + if (AL.getNumArgs() == 1 && + !S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr)) return; - } else if (LO.CPlusPlus && !LO.CPlusPlus17) - S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL; + } else if (!AL.getScopeName()) { + // The standard attribute cannot be applied to variable declarations such + // as a function pointer. + if (isa<VarDecl>(D)) + S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) + << AL << AL.isRegularKeywordAttribute() + << ExpectedFunctionOrClassOrEnum; + + // If this is spelled as the standard C++17 attribute, but not in C++17, + // warn about using it as an extension. If there are attribute arguments, + // then claim it's a C++20 extension instead. C23 supports this attribute + // with the message; no extension warning is needed there beyond the one + // already issued for accepting attributes in older modes. + const LangOptions &LO = S.getLangOpts(); + if (AL.getNumArgs() == 1) { + if (LO.CPlusPlus && !LO.CPlusPlus20) + S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL; + + if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr)) + return; + } else if (LO.CPlusPlus && !LO.CPlusPlus17) + S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL; + } } if ((!AL.isGNUAttribute() && diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp index fa7540c116e67..fe7d5ea79e9a7 100644 --- a/clang/test/SemaCXX/warn-unused-result.cpp +++ b/clang/test/SemaCXX/warn-unused-result.cpp @@ -364,3 +364,21 @@ void id_print_name() { ((int(*)())f)(); } } // namespace GH117975 + +namespace BuildStringOnClangScope { + +[[clang::warn_unused_result("Discarded result")]] +bool makeClangTrue() { return true; } + +[[gnu::warn_unused_result("Discarded result")]] +bool makeGccTrue() { return true; } + +void doClangThings() { + makeClangTrue(); // expected-warning {{ignoring return value of function declared with 'clang::warn_unused_result' attribute: Discarded result}} +} + +void doGccThings() { + makeGccTrue(); // expected-warning {{ignoring return value of function declared with 'gnu::warn_unused_result' attribute}} +} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits