Skip to content

Commit e35b01d

Browse files
authored
[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.
1 parent ea8ff79 commit e35b01d

File tree

3 files changed

+51
-21
lines changed

3 files changed

+51
-21
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,9 @@ related warnings within the method body.
475475
- Clang now disallows the use of attributes applied before an
476476
``extern template`` declaration (#GH79893).
477477

478+
- Clang will print the "reason" string argument passed on to
479+
``[[clang::warn_unused_result("reason")]]`` as part of the warning diagnostic.
480+
478481
Improvements to Clang's diagnostics
479482
-----------------------------------
480483

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2902,28 +2902,37 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
29022902
}
29032903

29042904
StringRef Str;
2905-
if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {
2906-
// The standard attribute cannot be applied to variable declarations such
2907-
// as a function pointer.
2908-
if (isa<VarDecl>(D))
2909-
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2910-
<< AL << AL.isRegularKeywordAttribute()
2911-
<< ExpectedFunctionOrClassOrEnum;
2912-
2913-
// If this is spelled as the standard C++17 attribute, but not in C++17,
2914-
// warn about using it as an extension. If there are attribute arguments,
2915-
// then claim it's a C++20 extension instead. C23 supports this attribute
2916-
// with the message; no extension warning is needed there beyond the one
2917-
// already issued for accepting attributes in older modes.
2918-
const LangOptions &LO = S.getLangOpts();
2919-
if (AL.getNumArgs() == 1) {
2920-
if (LO.CPlusPlus && !LO.CPlusPlus20)
2921-
S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
2922-
2923-
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
2905+
if (AL.isStandardAttributeSyntax()) {
2906+
// If this is spelled [[clang::warn_unused_result]] we look for an optional
2907+
// string literal. This is not gated behind any specific version of the
2908+
// standard.
2909+
if (AL.isClangScope()) {
2910+
if (AL.getNumArgs() == 1 &&
2911+
!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
29242912
return;
2925-
} else if (LO.CPlusPlus && !LO.CPlusPlus17)
2926-
S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2913+
} else if (!AL.getScopeName()) {
2914+
// The standard attribute cannot be applied to variable declarations such
2915+
// as a function pointer.
2916+
if (isa<VarDecl>(D))
2917+
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2918+
<< AL << AL.isRegularKeywordAttribute()
2919+
<< ExpectedFunctionOrClassOrEnum;
2920+
2921+
// If this is spelled as the standard C++17 attribute, but not in C++17,
2922+
// warn about using it as an extension. If there are attribute arguments,
2923+
// then claim it's a C++20 extension instead. C23 supports this attribute
2924+
// with the message; no extension warning is needed there beyond the one
2925+
// already issued for accepting attributes in older modes.
2926+
const LangOptions &LO = S.getLangOpts();
2927+
if (AL.getNumArgs() == 1) {
2928+
if (LO.CPlusPlus && !LO.CPlusPlus20)
2929+
S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
2930+
2931+
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
2932+
return;
2933+
} else if (LO.CPlusPlus && !LO.CPlusPlus17)
2934+
S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2935+
}
29272936
}
29282937

29292938
if ((!AL.isGNUAttribute() &&

clang/test/SemaCXX/warn-unused-result.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,21 @@ void id_print_name() {
364364
((int(*)())f)();
365365
}
366366
} // namespace GH117975
367+
368+
namespace BuildStringOnClangScope {
369+
370+
[[clang::warn_unused_result("Discarded result")]]
371+
bool makeClangTrue() { return true; }
372+
373+
[[gnu::warn_unused_result("Discarded result")]]
374+
bool makeGccTrue() { return true; }
375+
376+
void doClangThings() {
377+
makeClangTrue(); // expected-warning {{ignoring return value of function declared with 'clang::warn_unused_result' attribute: Discarded result}}
378+
}
379+
380+
void doGccThings() {
381+
makeGccTrue(); // expected-warning {{ignoring return value of function declared with 'gnu::warn_unused_result' attribute}}
382+
}
383+
384+
}

0 commit comments

Comments
 (0)