diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 0bf4615..f866132 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -262,15 +262,11 @@ public:
       if (visibility() < V)
         return;
 
-      // If one has explicit visibility and the other doesn't, keep the
-      // explicit one.
-      if (visibilityExplicit() && !E)
+      // If we have an explicit visibility, keep it
+      if (visibilityExplicit())
         return;
-      if (!visibilityExplicit() && E)
-        setVisibility(V, E);
 
-      // If both are explicit or both are implicit, keep the minimum.
-      setVisibility(minVisibility(visibility(), V), visibilityExplicit() || E);
+      setVisibility(V, E);
     }
     // Merge the visibility V, keeping the most restrictive one.
     // This is used for cases like merging the visibility of a template
@@ -278,12 +274,9 @@ public:
     // no argument should give it default visibility.
     void mergeVisibilityWithMin(Visibility V, bool E = false) {
       // Never increase the visibility
-      if (visibility() < V)
+      if (visibility() <= V)
         return;
 
-      // If this visibility is explicit, keep it.
-      if (visibilityExplicit() && !E)
-        return;
       setVisibility(V, E);
     }
     void mergeVisibility(LinkageInfo Other) {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 002bd2f..78bf3e2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -484,19 +484,12 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
 
   LinkageInfo LV;
 
-  bool DHasExplicitVisibility = false;
   // If we have an explicit visibility attribute, merge that in.
   if (F.ConsiderVisibilityAttributes) {
     if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
       LV.mergeVisibility(*Vis, true);
-
-      DHasExplicitVisibility = true;
     }
   }
-  // Ignore both global visibility and attributes when computing our
-  // parent's visibility if we already have an explicit one.
-  LVFlags ClassF =  DHasExplicitVisibility ?
-    LVFlags::CreateOnlyDeclLinkage() : F;
 
   // If we're paying attention to global visibility, apply
   // -finline-visibility-hidden if this is an inline method.
@@ -520,7 +513,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
     if (TSK != TSK_ExplicitInstantiationDeclaration &&
         TSK != TSK_ExplicitInstantiationDefinition &&
         F.ConsiderGlobalVisibility &&
-        !LV.visibilityExplicit() &&
         MD->getASTContext().getLangOpts().InlineVisibilityHidden &&
         MD->hasBody(Def) && Def->isInlined())
       LV.mergeVisibility(HiddenVisibility, true);
@@ -528,7 +520,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
 
   // Class members only have linkage if their class has external
   // linkage.
-  LV.merge(getLVForDecl(cast<RecordDecl>(D->getDeclContext()), ClassF));
+  LV.merge(getLVForDecl(cast<RecordDecl>(D->getDeclContext()), F));
   if (!isExternalLinkage(LV.linkage()))
     return LinkageInfo::none();
 
@@ -581,8 +573,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
     LinkageInfo TypeLV = getLVForType(VD->getType());
     if (TypeLV.linkage() != ExternalLinkage)
       LV.mergeLinkage(UniqueExternalLinkage);
-    if (!LV.visibilityExplicit())
-      LV.mergeVisibility(TypeLV);
+    LV.mergeVisibility(TypeLV);
   }
 
   return LV;
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 59fd7c2..16fea1c 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -28,6 +28,18 @@ namespace test28 {
   // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global
 }
 
+namespace test29 {
+#pragma GCC visibility push(hidden)
+  struct RECT {
+    int top;
+  };
+  __attribute__ ((visibility ("default"))) extern RECT data_rect;
+  RECT data_rect = { -1};
+#pragma GCC visibility pop
+  // CHECK: @_ZN6test299data_rectE = global
+  // CHECK-HIDDEN: @_ZN6test299data_rectE = global
+}
+
 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
 // CHECK: @_ZN5Test71aE = hidden global
 // CHECK: @_ZN5Test71bE = global
@@ -368,10 +380,10 @@ namespace Test18 {
   // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
   // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
-  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
+  // CHECK: declare void @_ZN6Test181AINS_1HEE3barEv()
   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
-  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
-  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
+  // CHECK: declare void @_ZN6Test181AINS_1HEE1B3fooEv()
+  // CHECK: declare void @_ZN6Test181AINS_1HEE1B3barEv()
   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
   // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
@@ -380,10 +392,10 @@ namespace Test18 {
   // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
-  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
+  // CHECK-HIDDEN: declare void @_ZN6Test181AINS_1HEE3barEv()
   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
-  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
-  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
+  // CHECK-HIDDEN: declare void @_ZN6Test181AINS_1HEE1B3fooEv()
+  // CHECK-HIDDEN: declare void @_ZN6Test181AINS_1HEE1B3barEv()
   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
 }
 
@@ -510,7 +522,7 @@ namespace PR10113 {
   };
   template class foo::bar<zed>;
   // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
-  // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
 }
 
 namespace PR11690 {
@@ -541,7 +553,7 @@ namespace PR11690_2 {
   };
   template class foo::zed<baz>;
   // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
-  // CHECK-HIDDEN: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
 }
 
 namespace test23 {
