aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-05-02 20:36:57 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-05-02 20:36:57 +0000
commit548d17c977959a5ed395ea1a407901f1314e575c (patch)
treeefcf7cdd9e9f75bfc5a2220dc0f50e11818ce56b
parent51c8bac81e103f334f0dafb1bf2d4c335ac3a28b (diff)
Walk the decls looking for the last one that has an attribute. We do have to walk
them, otherwise we cannot produce an error for both struct HIDDEN test4; // canonical struct test4; struct DEFAULT test4; and struct test5; // canonical struct HIDDEN test5; struct DEFAULT test5; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156016 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclAttr.cpp15
-rw-r--r--test/Sema/attr-visibility.c4
2 files changed, 13 insertions, 6 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 13bf0aa487..6b3f4f9734 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1757,13 +1757,16 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
- Decl *PrevDecl;
- if (isa<FunctionDecl>(D))
- PrevDecl = D->getMostRecentDecl()->getPreviousDecl();
- else
- PrevDecl = D->getCanonicalDecl();
+ // Find the last Decl that has an attribute.
+ VisibilityAttr *PrevAttr;
+ assert(D->redecls_begin() == D);
+ for (Decl::redecl_iterator I = D->redecls_begin(), E = D->redecls_end();
+ I != E; ++I) {
+ PrevAttr = I->getAttr<VisibilityAttr>() ;
+ if (PrevAttr)
+ break;
+ }
- VisibilityAttr *PrevAttr = PrevDecl ? PrevDecl->getAttr<VisibilityAttr>() : 0;
if (PrevAttr) {
VisibilityAttr::VisibilityType PrevVisibility = PrevAttr->getVisibility();
if (PrevVisibility != type) {
diff --git a/test/Sema/attr-visibility.c b/test/Sema/attr-visibility.c
index 499111f86c..4996dca5be 100644
--- a/test/Sema/attr-visibility.c
+++ b/test/Sema/attr-visibility.c
@@ -10,3 +10,7 @@ void test3() __attribute__((visibility("protected"))); // expected-warning {{tar
struct __attribute__((visibility("hidden"))) test4; // expected-note {{previous attribute is here}}
struct test4;
struct __attribute__((visibility("default"))) test4; // expected-error {{visibility does not match previous declaration}}
+
+struct test5;
+struct __attribute__((visibility("hidden"))) test5; // expected-note {{previous attribute is here}}
+struct __attribute__((visibility("default"))) test5; // expected-error {{visibility does not match previous declaration}}