aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-10-01 05:17:03 +0000
committerJohn McCall <rjmccall@apple.com>2011-10-01 05:17:03 +0000
commite82247a71a1a76e78f3b979b64d5f6412ab40266 (patch)
treedfe73fd7a7b7b163bee57b7bbadf0a54416dafdb /lib
parent130e5efd29a52a7cbd17c7b4a4744a320ee29692 (diff)
Hey, maybe we shouldn't silently ignore decl attributes
on declarators written as types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaDeclAttr.cpp28
-rw-r--r--lib/Sema/SemaExpr.cpp2
-rw-r--r--lib/Sema/SemaType.cpp12
3 files changed, 42 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 5802aaad96..d9e4df058d 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -3719,6 +3719,34 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
}
}
+/// checkUnusedDeclAttributes - Check a list of attributes to see if it
+/// contains any decl attributes that we should warn about.
+static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
+ for ( ; A; A = A->getNext()) {
+ // Only warn if the attribute is an unignored, non-type attribute.
+ if (A->isUsedAsTypeAttr()) continue;
+ if (A->getKind() == AttributeList::IgnoredAttribute) continue;
+
+ if (A->getKind() == AttributeList::UnknownAttribute) {
+ S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
+ << A->getName() << A->getRange();
+ } else {
+ S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
+ << A->getName() << A->getRange();
+ }
+ }
+}
+
+/// checkUnusedDeclAttributes - Given a declarator which is not being
+/// used to build a declaration, complain about any decl attributes
+/// which might be lying around on it.
+void Sema::checkUnusedDeclAttributes(Declarator &D) {
+ ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
+ ::checkUnusedDeclAttributes(*this, D.getAttributes());
+ for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
+ ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
+}
+
/// DeclClonePragmaWeak - clone existing decl (maybe definition),
/// #pragma weak needs a non-definition decl and source may not have one
NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0fea54b77d..d0a3f6b5ec 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4291,6 +4291,8 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
CheckExtraCXXDefaultArguments(D);
}
+ checkUnusedDeclAttributes(D);
+
QualType castType = castTInfo->getType();
Ty = CreateParsedType(castType, castTInfo);
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 25ec0b1477..9707804cf0 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -3064,6 +3064,9 @@ TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
if (D.isInvalidType())
return true;
+ // Make sure there are no unused decl attributes on the declarator.
+ checkUnusedDeclAttributes(D);
+
if (getLangOptions().CPlusPlus) {
// Check that there are no default arguments (C++ only).
CheckExtraCXXDefaultArguments(D);
@@ -3758,30 +3761,37 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
case AttributeList::AT_address_space:
HandleAddressSpaceTypeAttribute(type, attr, state.getSema());
+ attr.setUsedAsTypeAttr();
break;
OBJC_POINTER_TYPE_ATTRS_CASELIST:
if (!handleObjCPointerTypeAttr(state, attr, type))
distributeObjCPointerTypeAttr(state, attr, type);
+ attr.setUsedAsTypeAttr();
break;
case AttributeList::AT_vector_size:
HandleVectorSizeAttr(type, attr, state.getSema());
+ attr.setUsedAsTypeAttr();
break;
case AttributeList::AT_ext_vector_type:
if (state.getDeclarator().getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_typedef)
HandleExtVectorTypeAttr(type, attr, state.getSema());
+ attr.setUsedAsTypeAttr();
break;
case AttributeList::AT_neon_vector_type:
HandleNeonVectorTypeAttr(type, attr, state.getSema(),
VectorType::NeonVector, "neon_vector_type");
+ attr.setUsedAsTypeAttr();
break;
case AttributeList::AT_neon_polyvector_type:
HandleNeonVectorTypeAttr(type, attr, state.getSema(),
VectorType::NeonPolyVector,
"neon_polyvector_type");
+ attr.setUsedAsTypeAttr();
break;
case AttributeList::AT_opencl_image_access:
HandleOpenCLImageAccessAttribute(type, attr, state.getSema());
+ attr.setUsedAsTypeAttr();
break;
case AttributeList::AT_ns_returns_retained:
@@ -3790,6 +3800,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
// fallthrough into the function attrs
FUNCTION_TYPE_ATTRS_CASELIST:
+ attr.setUsedAsTypeAttr();
+
// Never process function type attributes as part of the
// declaration-specifiers.
if (isDeclSpec)