diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 3b37890..0696b6c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4660,6 +4660,27 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) {
   CheckShadow(S, D, R);
 }
 
+static bool hasCLanguageLinkage(const NamedDecl *ND) {
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+  if (FD)
+    return FD->hasCLanguageLinkage();
+  const VarDecl *VD = dyn_cast<VarDecl>(ND);
+  if (VD)
+    return VD->hasCLanguageLinkage();
+  llvm_unreachable("Only defined for variables and functions.");
+}
+
+template<typename T>
+static bool mayConflictWithNonVisibleExternC(const T *ND) {
+  StorageClass SC = ND->getStorageClass();
+  if (SC == SC_Static)
+    return false;
+  if (isa<VarDecl>(ND) && SC == SC_None &&
+      ND->getDeclContext()->isFunctionOrMethod())
+    return false;
+  return true;
+}
+
 /// \brief Perform semantic checking on a newly-created variable
 /// declaration.
 ///
@@ -4762,14 +4783,16 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
     NewVD->setTypeSourceInfo(FixedTInfo);
   }
 
-  if (Previous.empty() && NewVD->isExternC()) {
-    // Since we did not find anything by this name and we're declaring
-    // an extern "C" variable, look for a non-visible extern "C"
-    // declaration with the same name.
+  if (Previous.empty() && mayConflictWithNonVisibleExternC(NewVD)) {
+    // Since we did not find anything by this name, look for a non-visible
+    // extern "C" declaration with the same name.
     llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
       = findLocallyScopedExternalDecl(NewVD->getDeclName());
-    if (Pos != LocallyScopedExternalDecls.end())
-      Previous.addDecl(Pos->second);
+    if (Pos != LocallyScopedExternalDecls.end()) {
+      NamedDecl *ND = Pos->second;
+      if (ND && hasCLanguageLinkage(ND))
+        Previous.addDecl(Pos->second);
+    }
   }
 
   if (T->isVoidType() && !NewVD->hasExternalStorage()) {
@@ -6112,14 +6135,16 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
          && "Variably modified return types are not handled here");
 
   // Check for a previous declaration of this name.
-  if (Previous.empty() && NewFD->isExternC()) {
-    // Since we did not find anything by this name and we're declaring
-    // an extern "C" function, look for a non-visible extern "C"
-    // declaration with the same name.
+  if (Previous.empty() && mayConflictWithNonVisibleExternC(NewFD)) {
+    // Since we did not find anything by this name, look for a non-visible
+    // extern "C" declaration with the same name.
     llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
       = findLocallyScopedExternalDecl(NewFD->getDeclName());
-    if (Pos != LocallyScopedExternalDecls.end())
-      Previous.addDecl(Pos->second);
+    if (Pos != LocallyScopedExternalDecls.end()) {
+      NamedDecl *ND = Pos->second;
+      if (ND && hasCLanguageLinkage(ND))
+        Previous.addDecl(ND);
+    }
   }
 
   bool Redeclaration = false;
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
index b9d1f23..dd325d7 100644
--- a/test/SemaCXX/function-redecl.cpp
+++ b/test/SemaCXX/function-redecl.cpp
@@ -116,3 +116,21 @@ bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does
 }
 void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
 }
+
+namespace test2 {
+  extern "C" {
+    void f() {
+      extern void g(int); // expected-note {{previous declaration is here}}
+    }
+  }
+  int g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+}
+
+namespace test3 {
+  extern "C" {
+    void f() {
+      extern int x; // expected-note {{previous definition is here}}
+    }
+  }
+  float x; // expected-error {{redefinition of 'x' with a different type: 'float' vs 'int'}}
+}
