Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 209650)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -3144,7 +3144,7 @@
                                      SourceLocation IdLoc,
                                      IdentifierInfo *Id);
 
-  Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D);
+  Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D, bool FnCatch);
 
   StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
                                 Decl *ExDecl, Stmt *HandlerBlock);
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp	(revision 209650)
+++ lib/Parse/ParseStmt.cpp	(working copy)
@@ -2685,7 +2685,8 @@
 
     Declarator ExDecl(DS, Declarator::CXXCatchContext);
     ParseDeclarator(ExDecl);
-    ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl);
+    ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl,
+                                                     FnCatch);
   } else
     ConsumeToken();
 
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp	(revision 209650)
+++ lib/Sema/SemaDeclCXX.cpp	(working copy)
@@ -11262,7 +11262,7 @@
 
 /// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch
 /// handler.
-Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D, bool FnCatch) {
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   bool Invalid = D.isInvalidType();
 
@@ -11279,13 +11279,17 @@
                                              LookupOrdinaryName,
                                              ForRedeclaration)) {
     // The scope should be freshly made just for us. There is just no way
-    // it contains any previous declaration.
+    // it contains any previous declaration, except for function parameters in
+    // a function-try-block's catch statement.
     assert(!S->isDeclScope(PrevDecl));
-    if (PrevDecl->isTemplateParameter()) {
+    if (FnCatch && isa<ParmVarDecl>(PrevDecl)) {
+      Diag(D.getIdentifierLoc(), diag::err_redefinition)
+        << D.getIdentifier();
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      Invalid = true;
+    } else if (PrevDecl->isTemplateParameter())
       // Maybe we will complain about the shadowed template parameter.
       DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
-      PrevDecl = nullptr;
-    }
   }
 
   if (D.getCXXScopeSpec().isSet() && !Invalid) {
Index: test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
===================================================================
--- test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp	(revision 209650)
+++ test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp	(working copy)
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// XFAIL: *
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify %s
 
 class C {
 public:
Index: test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
===================================================================
--- test/CXX/basic/basic.scope/basic.scope.local/p2.cpp	(revision 209650)
+++ test/CXX/basic/basic.scope/basic.scope.local/p2.cpp	(working copy)
@@ -9,8 +9,8 @@
 } catch (...) {
 }
 
-void func3(int i) try { // FIXME: note {{previous definition is here}}
-} catch (int i) { // FIXME: error {{redefinition of 'i'}}
+void func3(int i) try { // expected-note {{previous definition is here}}
+} catch (int i) { // expected-error {{redefinition of 'i'}}
 }
 
 void func4(int i) try { // expected-note{{previous definition is here}}
@@ -58,3 +58,9 @@
       int b; // FIXME: decide whether this is valid
     }
 }
+
+void func11(int a) {
+  try {
+  } catch (int a) {  // OK
+  }
+}
