From 44d1e0af59188b39e5b55df92f872cd13baaa561 Mon Sep 17 00:00:00 2001 From: Olivier Goffart <ogoffart@woboq.com> Date: Thu, 16 Jun 2016 21:39:46 +0000 Subject: [PATCH] Functions declared in a scope should not hide previous declaration in earlier scopes This code should be an error: void foo(int); void f3() { int foo(float); { float foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} } } the foo(float) function declared at function scope should not hide the float(int) while trying to redeclare functions. Differential Revision: http://reviews.llvm.org/D19763 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272961 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaLookup.cpp | 23 +++++++++++++---------- test/SemaCXX/function-redecl.cpp | 9 ++++++++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index e761436683e..37db9aec637 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1078,32 +1078,35 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) { DeclContext *Ctx = S->getEntity(); - + bool SearchNamespaceScope = true; // Check whether the IdResolver has anything in this scope. - bool Found = false; for (; I != IEnd && S->isDeclScope(*I); ++I) { if (NamedDecl *ND = R.getAcceptableDecl(*I)) { - if (NameKind == LookupRedeclarationWithLinkage) { + if (NameKind == LookupRedeclarationWithLinkage && + !(*I)->isTemplateParameter()) { + // If it's a template parameter, we still find it, so we can diagnose + // the invalid redeclaration. + // Determine whether this (or a previous) declaration is // out-of-scope. if (!LeftStartingScope && !Initial->isDeclScope(*I)) LeftStartingScope = true; // If we found something outside of our starting scope that - // does not have linkage, skip it. If it's a template parameter, - // we still find it, so we can diagnose the invalid redeclaration. - if (LeftStartingScope && !((*I)->hasLinkage()) && - !(*I)->isTemplateParameter()) { + // does not have linkage, skip it. + if (LeftStartingScope && !((*I)->hasLinkage())) { R.setShadowed(); continue; } + } else { + // We found something in this scope, we should not look at the + // namespace scope + SearchNamespaceScope = false; } - - Found = true; R.addDecl(ND); } } - if (Found) { + if (!SearchNamespaceScope) { R.resolveKind(); if (S->isClassScope()) if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(Ctx)) diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp index 2bc0d90cd62..f91e670c0c3 100644 --- a/test/SemaCXX/function-redecl.cpp +++ b/test/SemaCXX/function-redecl.cpp @@ -7,7 +7,7 @@ namespace N { void bar(int); // expected-note 2{{previous declaration is here}} } - void foo(int); // expected-note 2{{previous declaration is here}} + void foo(int); // expected-note 3{{previous declaration is here}} void f2() { int foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} @@ -25,6 +25,13 @@ namespace N { } } } + + void f3() { + int foo(float); + { + float foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}} + } + } } class A { -- GitLab