diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 28 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 12 |
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) |