aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2009-12-22 23:59:52 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2009-12-22 23:59:52 +0000
commitf857798fa77ac50c6d0a262d96ad6176187190e3 (patch)
tree0e49f8279aa4349cf2a9c2cffc75bccdee9e3fda
parent6e790ab61bf4835944971955e84279112833ef0c (diff)
warn when attribute warn_unused_result is applied to void functions.
while at it, remove an outdated FIXME git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91946 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp7
-rw-r--r--test/Sema/unused-expr.c6
3 files changed, 12 insertions, 3 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index eece90b42a..cd6f6894d9 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/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/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 718db0437f..e95f479bd8 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/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/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
index 284818dc58..30f6aee26b 100644
--- a/test/Sema/unused-expr.c
+++ b/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}}