[cfe-commits] r160227 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/Sema/attr-decl-after-definition.c
Rafael Espindola
rafael.espindola at gmail.com
Sat Jul 14 18:33:40 PDT 2012
Author: rafael
Date: Sat Jul 14 20:33:40 2012
New Revision: 160227
URL: http://llvm.org/viewvc/llvm-project?rev=160227&view=rev
Log:
Without this patch clang warns on
struct __attribute__((visibility("hidden"))) zed {
};
struct __attribute__((visibility("hidden"))) zed;
Which is a bit silly and got a lot noisier now that we correctly handle
visibility pragmas. This patch fixes that and also has some extra quality
improvements:
* We now produce an error instead of a warning for
struct __attribute__((visibility("hidden"))) zed {
};
struct __attribute__((visibility("default"))) zed;
* The "after definition" warning now points to the new attribute that is
ignored instead of pointing to the declaration.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Sema/attr-decl-after-definition.c
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=160227&r1=160226&r2=160227&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jul 14 20:33:40 2012
@@ -1767,16 +1767,46 @@
return NULL;
}
+static bool hasAttribute(const Decl *D, attr::Kind Kind) {
+ for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end();
+ I != E; ++I) {
+ Attr *Attribute = *I;
+ if (Attribute->getKind() == Kind)
+ return true;
+ }
+ return false;
+}
+
+/// checkNewAttributesAfterDef - If we already have a definition, check that
+/// there are no new attributes in this declaration.
+static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
+ if (!New->hasAttrs())
+ return;
+
+ const Decl *Def = getDefinition(Old);
+ if (!Def || Def == New)
+ return;
+
+ AttrVec &NewAttributes = New->getAttrs();
+ for (unsigned I = 0, E = NewAttributes.size(); I != E;) {
+ const Attr *NewAttribute = NewAttributes[I];
+ if (hasAttribute(Def, NewAttribute->getKind())) {
+ ++I;
+ continue; // regular attr merging will take care of validating this.
+ }
+ S.Diag(NewAttribute->getLocation(),
+ diag::warn_attribute_precede_definition);
+ S.Diag(Def->getLocation(), diag::note_previous_definition);
+ NewAttributes.erase(NewAttributes.begin() + I);
+ --E;
+ }
+}
+
/// mergeDeclAttributes - Copy attributes from the Old decl to the New one.
void Sema::mergeDeclAttributes(Decl *New, Decl *Old,
bool MergeDeprecation) {
// attributes declared post-definition are currently ignored
- const Decl *Def = getDefinition(Old);
- if (Def && Def != New && New->hasAttrs()) {
- Diag(New->getLocation(), diag::warn_attribute_precede_definition);
- Diag(Def->getLocation(), diag::note_previous_definition);
- New->dropAttrs();
- }
+ checkNewAttributesAfterDef(*this, New, Old);
if (!Old->hasAttrs())
return;
Modified: cfe/trunk/test/Sema/attr-decl-after-definition.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-decl-after-definition.c?rev=160227&r1=160226&r2=160227&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-decl-after-definition.c (original)
+++ cfe/trunk/test/Sema/attr-decl-after-definition.c Sat Jul 14 20:33:40 2012
@@ -14,9 +14,26 @@
int bar __attribute__((used));
extern int bar __attribute__((weak));
int bar = 0; // expected-note {{previous definition is here}}
-int bar __attribute__((weak)); // expected-warning {{must precede definition}}
+int bar __attribute__((weak)); // no warning as it matches the existing
+ // attribute.
+int bar __attribute__((used,
+ visibility("hidden"))); // expected-warning {{must precede definition}}
int bar;
struct zed { // expected-note {{previous definition is here}}
};
struct __attribute__((visibility("hidden"))) zed; // expected-warning {{must precede definition}}
+
+struct __attribute__((visibility("hidden"))) zed2 {
+};
+struct __attribute__((visibility("hidden"))) zed2;
+
+struct __attribute__((visibility("hidden"))) zed3 { // expected-note {{previous definition is here}}
+};
+struct __attribute__((visibility("hidden"),
+ packed // expected-warning {{must precede definition}}
+ )) zed3;
+
+struct __attribute__((visibility("hidden"))) zed4 { // expected-note {{previous attribute is here}}
+};
+struct __attribute__((visibility("default"))) zed4; // expected-error {{visibility does not match previous declaration}}
More information about the cfe-commits
mailing list