diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 7 | ||||
| -rw-r--r-- | clang/test/Sema/unused-expr.c | 6 |
3 files changed, 12 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index eece90b42a6..cd6f6894d90 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -682,6 +682,8 @@ def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< def warn_attribute_ignored : Warning<"%0 attribute ignored">; def warn_attribute_precede_definition : Warning< "attribute declaration must precede definition">; +def warn_attribute_void_function : Warning< + "attribute %0 cannot be applied to functions without return value">; def warn_attribute_weak_on_field : Warning< "__weak attribute cannot be specified on a field declaration">; def warn_attribute_weak_on_local : Warning< diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 718db0437f4..e95f479bd8e 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -730,13 +730,18 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) return; } - // TODO: could also be applied to methods? if (!isFunctionOrMethod(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << Attr.getName() << 0 /*function*/; return; } + if (getFunctionType(D)->getResultType()->isVoidType()) { + S.Diag(Attr.getLoc(), diag::warn_attribute_void_function) + << Attr.getName(); + return; + } + D->addAttr(::new (S.Context) WarnUnusedResultAttr()); } diff --git a/clang/test/Sema/unused-expr.c b/clang/test/Sema/unused-expr.c index 284818dc581..30f6aee26b4 100644 --- a/clang/test/Sema/unused-expr.c +++ b/clang/test/Sema/unused-expr.c @@ -87,17 +87,19 @@ int fn3() __attribute__ ((const)); int t6() { if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0) // no warnings return -1; - + fn1(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} fn2(92, 21); // expected-warning {{ignoring return value of function declared with pure attribute}} fn3(42); // expected-warning {{ignoring return value of function declared with const attribute}} return 0; } -int t7 __attribute__ ((warn_unused_result)); // expected-warning {{warning: 'warn_unused_result' attribute only applies to function types}} +int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to function types}} // PR4010 int (*fn4)(void) __attribute__ ((warn_unused_result)); void t8() { fn4(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}} } + +void t9() __attribute__((warn_unused_result)); // expected-warning {{attribute 'warn_unused_result' cannot be applied to functions without return value}} |

