From 548d17c977959a5ed395ea1a407901f1314e575c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 2 May 2012 20:36:57 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaDeclAttr.cpp | 15 +++++++++------ test/Sema/attr-visibility.c | 4 ++++ 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(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() ; + if (PrevAttr) + break; + } - VisibilityAttr *PrevAttr = PrevDecl ? PrevDecl->getAttr() : 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}} -- 2.40.0