mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
Hey, maybe we shouldn't silently ignore decl attributes
on declarators written as types. llvm-svn: 140931
This commit is contained in:
@@ -1435,6 +1435,8 @@ def warn_label_attribute_not_unused : Warning<
|
||||
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
|
||||
|
||||
@@ -73,6 +73,9 @@ private:
|
||||
/// 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;
|
||||
@@ -123,7 +126,8 @@ private:
|
||||
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());
|
||||
}
|
||||
@@ -139,8 +143,8 @@ private:
|
||||
: 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);
|
||||
@@ -287,6 +291,9 @@ public:
|
||||
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);
|
||||
|
||||
|
||||
@@ -1829,6 +1829,8 @@ public:
|
||||
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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -4291,6 +4291,8 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
|
||||
CheckExtraCXXDefaultArguments(D);
|
||||
}
|
||||
|
||||
checkUnusedDeclAttributes(D);
|
||||
|
||||
QualType castType = castTInfo->getType();
|
||||
Ty = CreateParsedType(castType, castTInfo);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -11,11 +11,11 @@ typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
|
||||
|
||||
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)
|
||||
|
||||
@@ -37,3 +37,7 @@ _Decimal32 x; // expected-error {{GNU decimal type extension not supported}}
|
||||
|
||||
// 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}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user