Skip to content

Commit 2ec5520

Browse files
committed
Disallow [[nodiscard]] on a function pointer declaration.
This is not allowed by [dcl.attr.nodiscard]p1 for the standard attribute, but is still supported for the [[clang::warn_unused_result]] spelling.
1 parent fdf9bad commit 2ec5520

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,6 +2826,12 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
28262826

28272827
StringRef Str;
28282828
if ((AL.isCXX11Attribute() || AL.isC2xAttribute()) && !AL.getScopeName()) {
2829+
// The standard attribute cannot be applied to variable declarations such
2830+
// as a function pointer.
2831+
if (isa<VarDecl>(D))
2832+
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
2833+
<< AL << "functions, classes, or enumerations";
2834+
28292835
// If this is spelled as the standard C++17 attribute, but not in C++17,
28302836
// warn about using it as an extension. If there are attribute arguments,
28312837
// then claim it's a C++2a extension instead.

clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void f() {
2626
(void)get_e();
2727
}
2828

29-
[[nodiscard]] volatile char &(*fp)();
29+
[[nodiscard]] volatile char &(*fp)(); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}
3030
void g() {
3131
fp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
3232

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,11 @@ void g() {
246246
f(b); // expected-warning {{ignoring return value}}
247247
}
248248
} // namespace PR39837
249+
250+
namespace PR45520 {
251+
[[nodiscard]] bool (*f)(); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}
252+
[[clang::warn_unused_result]] bool (*g)();
253+
__attribute__((warn_unused_result)) bool (*h)();
254+
255+
void i([[nodiscard]] bool (*fp)()); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}
256+
}

0 commit comments

Comments
 (0)