From: Aaron Ballman Date: Mon, 2 Jun 2014 13:10:07 +0000 (+0000) Subject: The exception-declaration for a function-try-block cannot redeclare a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f36b6747fafc1fe874d4000d9788f2fba81de744;p=clang The exception-declaration for a function-try-block cannot redeclare a function parameter. One of our existing test cases was XFAILed because of this. This fixes the issue and un-XFAILs the test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@210026 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 8a40a2e15a..36e353e895 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -11353,13 +11353,17 @@ Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { 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 (isDeclInScope(PrevDecl, CurContext, S)) { + 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) { diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp index 7df0f536cf..c59c4a550d 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s -// XFAIL: * class C { public: @@ -10,8 +9,13 @@ C::C(int a, // expected-note {{previous definition}} int b) // expected-note {{previous definition}} try { int c; - } catch (int a) { // expected-error {{redefinition of 'a'}} int b; // expected-error {{redefinition of 'b'}} ++c; // expected-error {{use of undeclared identifier 'c'}} } + +void f(int i) { + struct S { + void g() try {} catch (int i) {}; // OK + }; +} diff --git a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp index 7c7b84d678..1b4199155f 100644 --- a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp +++ b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp @@ -9,8 +9,8 @@ void func2(int i) try { // expected-note{{previous definition is here}} } 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 @@ void func10() { int b; // FIXME: decide whether this is valid } } + +void func11(int a) { + try { + } catch (int a) { // OK + } +}