aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDeclAttr.cpp30
-rw-r--r--lib/Sema/SemaType.cpp4
-rw-r--r--test/Sema/attr-noreturn.c2
3 files changed, 18 insertions, 18 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index ccc0c2df98..52d9f58d37 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -467,10 +467,11 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
+ Sema &S, bool EmitDiagnostics) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ if (EmitDiagnostics)
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
return false;
}
@@ -478,10 +479,11 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
ValueDecl *VD = dyn_cast<ValueDecl>(d);
if (VD == 0 || (!VD->getType()->isBlockPointerType()
&& !VD->getType()->isFunctionPointerType())) {
- S.Diag(Attr.getLoc(),
- Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
- : diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << 0 /*function*/;
+ if (EmitDiagnostics)
+ S.Diag(Attr.getLoc(),
+ Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
+ : diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << 0 /*function*/;
return false;
}
}
@@ -490,21 +492,17 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
}
static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- // NOTE: We don't add the attribute to a FunctionDecl because the noreturn
- // trait will be part of the function's type.
-
- // Don't apply as a decl attribute to ValueDecl.
- // FIXME: probably ought to diagnose this.
- if (isa<ValueDecl>(d))
- return;
-
- if (HandleCommonNoReturnAttr(d, Attr, S))
+ /*
+ Do check for well-formedness, but do not emit diagnostics:
+ it was already emitted by Sema::ProcessFnAttr().
+ */
+ if (HandleCommonNoReturnAttr(d, Attr, S, /*EmitDiagnostic=*/false))
d->addAttr(::new (S.Context) NoReturnAttr());
}
static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
- if (HandleCommonNoReturnAttr(d, Attr, S))
+ if (HandleCommonNoReturnAttr(d, Attr, S, true))
d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 882784b602..dc78fd633f 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1912,8 +1912,8 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result,
// type, but others can be present in the type specifiers even though they
// apply to the decl. Here we apply type attributes and ignore the rest.
for (; AL; AL = AL->getNext()) {
- // If this is an attribute we can handle, do so now, otherwise, add it to
- // the LeftOverAttrs list for rechaining.
+ // If this is an attribute we can handle, do so now,
+ // otherwise, add it to the FnAttrs list for rechaining.
switch (AL->getKind()) {
default: break;
diff --git a/test/Sema/attr-noreturn.c b/test/Sema/attr-noreturn.c
index b17f9fd129..5333a2c13f 100644
--- a/test/Sema/attr-noreturn.c
+++ b/test/Sema/attr-noreturn.c
@@ -40,3 +40,5 @@ f5 (unsigned long size)
__attribute__((noreturn)) void f(__attribute__((noreturn)) void (*x)(void)) {
x();
}
+
+typedef void (*Fun)(void) __attribute__ ((noreturn(2))); // expected-error {{attribute requires 0 argument(s)}}