aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-07-12 04:32:30 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-07-12 04:32:30 +0000
commitf729ce0b231e045b8e7db61e85e87186c09db238 (patch)
tree22e0d6eed143b39e09c9dc292a162bf9ea49e837
parent6a1f94b89bb497522ad0601350cbd47068fce5f1 (diff)
Ignore visibility attributes after definitions. This matches newer (4.7) gcc's
behavior and is the first step in fixing pr13338. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160104 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp8
-rw-r--r--test/CodeGenCXX/pragma-visibility.cpp8
-rw-r--r--test/SemaCXX/attr-visibility.cpp4
4 files changed, 15 insertions, 8 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index ebbdb8b263..769285a0b8 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1637,6 +1637,9 @@ def err_attribute_aligned_greater_than_8192 : Error<
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"'%0' redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
+def warn_attribute_after_definition_ignored : Warning<
+ "attribute %0 after definition is ignored">,
+ InGroup<IgnoredAttributes>;
def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
def warn_unhandled_ms_attribute_ignored : Warning<
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index ebd9180ec6..ba1b4f77fc 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4700,6 +4700,14 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
AdjustDeclIfTemplate(TagDecl);
+ for (const AttributeList* l = AttrList; l; l = l->getNext()) {
+ if (l->getKind() != AttributeList::AT_Visibility)
+ continue;
+ l->setInvalid();
+ Diag(l->getLoc(), diag::warn_attribute_after_definition_ignored) <<
+ l->getName();
+ }
+
ActOnFields(S, RLoc, TagDecl, llvm::makeArrayRef(
// strict aliasing violation!
reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
diff --git a/test/CodeGenCXX/pragma-visibility.cpp b/test/CodeGenCXX/pragma-visibility.cpp
index e54626ee2e..9b54a1813c 100644
--- a/test/CodeGenCXX/pragma-visibility.cpp
+++ b/test/CodeGenCXX/pragma-visibility.cpp
@@ -17,14 +17,6 @@ int x2::y = 10;
#pragma GCC visibility pop
#pragma GCC visibility push(hidden)
-struct x3 {
- static int y;
-} __attribute((visibility("default")));
-int x3::y = 10;
-// CHECK: @_ZN2x31yE = global
-#pragma GCC visibility pop
-
-#pragma GCC visibility push(hidden)
template<class T> struct x4 {
static int y;
};
diff --git a/test/SemaCXX/attr-visibility.cpp b/test/SemaCXX/attr-visibility.cpp
index 26dc67c6de..05aa5a33c7 100644
--- a/test/SemaCXX/attr-visibility.cpp
+++ b/test/SemaCXX/attr-visibility.cpp
@@ -14,3 +14,7 @@ template <>
__attribute__((visibility("default"))) // expected-error {{visibility does not match previous declaration}}
void foo<int>() {
}
+
+struct x3 {
+ static int y;
+} __attribute((visibility("default"))); // expected-warning {{attribute 'visibility' after definition is ignored}}