From e5a91464bc56d201f4f5c6db8b7900e89235d5a8 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 27 Feb 2016 02:36:43 +0000 Subject: [PATCH] Fix bug in using shadow decl checking: a using shadow decl should not conflict with a prior UsingDecl -- those should not even really be found by the lookup here, except that we use the same lookup results for two different checks, and the other check needs them. This happens to work in *almost all* cases, because either the lookup results list the UsingDecl first (and the NonTag result gets replaced by something else) or because the problematic declaration is a function (which causes us to use different logic to detect conflicts). This can also be triggered from a state only reachable through modules (where the name lookup results can contain multiple UsingDecls in the same scope). llvm-svn: 262105 --- clang/lib/Sema/SemaDeclCXX.cpp | 6 ++++++ clang/test/SemaCXX/using-decl-1.cpp | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 3890120..e7c3b6a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7796,6 +7796,12 @@ bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig, for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); + // We can have UsingDecls in our Previous results because we use the same + // LookupResult for checking whether the UsingDecl itself is a valid + // redeclaration. + if (isa(D)) + continue; + if (IsEquivalentForUsingDecl(Context, D, Target)) { if (UsingShadowDecl *Shadow = dyn_cast(*I)) PrevShadow = Shadow; diff --git a/clang/test/SemaCXX/using-decl-1.cpp b/clang/test/SemaCXX/using-decl-1.cpp index ec45b31..e17612d 100644 --- a/clang/test/SemaCXX/using-decl-1.cpp +++ b/clang/test/SemaCXX/using-decl-1.cpp @@ -338,3 +338,26 @@ struct B : A { enum { X = sizeof(field) }; }; } + +namespace tag_vs_var { + namespace N { + struct X {}; + + struct Y {}; + int Y; + + int Z; + } + using N::X; + using N::Y; + using N::Z; + + namespace N { + int X; + + struct Z {}; + } + using N::X; + using N::Y; + using N::Z; +} -- 2.7.4