def err_invalid_pcs : Error<"Invalid PCS type">;
def err_attribute_can_be_applied_only_to_value_decl : Error<
"%0 attribute can only be applied to value declarations">;
+def warn_attribute_not_on_decl : Error<
+ "%0 attribute ignored when parsing type">;
// Availability attribute
/// True if already diagnosed as invalid.
mutable unsigned Invalid : 1;
+ /// True if this attribute was used as a type attribute.
+ mutable unsigned UsedAsTypeAttr : 1;
+
/// True if this has the extra information associated with an
/// availability attribute.
unsigned IsAvailability : 1;
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
NumArgs(numArgs),
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false),
- IsAvailability(false), NextInPosition(0), NextInPool(0) {
+ UsedAsTypeAttr(false), IsAvailability(false),
+ NextInPosition(0), NextInPool(0) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
AttrKind = getKind(getName());
}
: AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
- Invalid(false), IsAvailability(true), UnavailableLoc(unavailable),
- NextInPosition(0), NextInPool(0) {
+ Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
+ UnavailableLoc(unavailable), NextInPosition(0), NextInPool(0) {
new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
bool isInvalid() const { return Invalid; }
void setInvalid(bool b = true) const { Invalid = b; }
+ bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
+ void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
+
Kind getKind() const { return Kind(AttrKind); }
static Kind getKind(const IdentifierInfo *Name);
void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
bool NonInheritable = true, bool Inheritable = true);
+ void checkUnusedDeclAttributes(Declarator &D);
+
bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC);
bool CheckNoReturnAttr(const AttributeList &attr);
}
}
+/// 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,
CheckExtraCXXDefaultArguments(D);
}
+ checkUnusedDeclAttributes(D);
+
QualType castType = castTInfo->getType();
Ty = CreateParsedType(castType, castTInfo);
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);
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:
// fallthrough into the function attrs
FUNCTION_TYPE_ATTRS_CASELIST:
+ attr.setUsedAsTypeAttr();
+
// Never process function type attributes as part of the
// declaration-specifiers.
if (isDeclSpec)
void * __ptr64 PtrToPtr64(const void *p)
{
- return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p );
+ return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p ); // expected-warning {{unknown attribute '__ptr64' ignored}}
}
void * __ptr32 PtrToPtr32(const void *p)
{
- return((void * __ptr32) (unsigned __int32) (ULONG_PTR)p );
+ return((void * __ptr32) (unsigned __int32) (ULONG_PTR)p ); // expected-warning {{unknown attribute '__ptr32' ignored}}
}
void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
// rdar://6880951
int __attribute__ ((vector_size (8), vector_size (8))) v; // expected-error {{invalid vector element type}}
+
+void test(int i) {
+ char c = (char __attribute__((align(8)))) i; // expected-error {{'align' attribute ignored when parsing type}}
+}