Author: rsmith Date: Fri Sep 11 17:39:35 2015 New Revision: 247486 URL: http://llvm.org/viewvc/llvm-project?rev=247486&view=rev Log: [modules] When picking one of two template declarations as a lookup result, it's not sufficient to prefer the declaration with more default arguments, or the one that's visible; they might both be visible, but one of them might have a visible default argument where the other has a hidden default argument.
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp cfe/trunk/test/Modules/Inputs/template-default-args/a.h cfe/trunk/test/Modules/Inputs/template-default-args/module.modulemap cfe/trunk/test/Modules/template-default-args.cpp Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=247486&r1=247485&r2=247486&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Sep 11 17:39:35 2015 @@ -387,6 +387,8 @@ static bool isPreferredLookupResult(Sema // If D has more default arguments, it is preferred. if (DMin != EMin) return DMin < EMin; + // FIXME: When we track visibility for default function arguments, check + // that we pick the declaration with more visible default arguments. } // Pick the template with more default template arguments. @@ -394,9 +396,22 @@ static bool isPreferredLookupResult(Sema auto *ETD = cast<TemplateDecl>(EUnderlying); unsigned DMin = DTD->getTemplateParameters()->getMinRequiredArguments(); unsigned EMin = ETD->getTemplateParameters()->getMinRequiredArguments(); - // If D has more default arguments, it is preferred. + // If D has more default arguments, it is preferred. Note that default + // arguments (and their visibility) is monotonically increasing across the + // redeclaration chain, so this is a quick proxy for "is more recent". if (DMin != EMin) return DMin < EMin; + // If D has more *visible* default arguments, it is preferred. Note, an + // earlier default argument being visible does not imply that a later + // default argument is visible, so we can't just check the first one. + for (unsigned I = DMin, N = DTD->getTemplateParameters()->size(); + I != N; ++I) { + if (!S.hasVisibleDefaultArgument( + ETD->getTemplateParameters()->getParam(I)) && + S.hasVisibleDefaultArgument( + DTD->getTemplateParameters()->getParam(I))) + return true; + } } // For most kinds of declaration, it doesn't really matter which one we pick. Modified: cfe/trunk/test/Modules/Inputs/template-default-args/a.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/template-default-args/a.h?rev=247486&r1=247485&r2=247486&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/template-default-args/a.h (original) +++ cfe/trunk/test/Modules/Inputs/template-default-args/a.h Fri Sep 11 17:39:35 2015 @@ -9,4 +9,8 @@ template<typename T = int> struct H; template<typename T> struct J {}; template<typename T = int> struct J; struct K : J<> {}; +template<typename T = void> struct L; +struct FriendL { + template<typename T> friend struct L; +}; END Modified: cfe/trunk/test/Modules/Inputs/template-default-args/module.modulemap URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/template-default-args/module.modulemap?rev=247486&r1=247485&r2=247486&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/template-default-args/module.modulemap (original) +++ cfe/trunk/test/Modules/Inputs/template-default-args/module.modulemap Fri Sep 11 17:39:35 2015 @@ -3,3 +3,6 @@ module X { module B { header "b.h" } module C { header "c.h" } } +module Y { + module D { header "d.h" } +} Modified: cfe/trunk/test/Modules/template-default-args.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/template-default-args.cpp?rev=247486&r1=247485&r2=247486&view=diff ============================================================================== --- cfe/trunk/test/Modules/template-default-args.cpp (original) +++ cfe/trunk/test/Modules/template-default-args.cpp Fri Sep 11 17:39:35 2015 @@ -13,6 +13,7 @@ template<typename T = int, typename U = END #include "b.h" +#include "d.h" BEGIN template<typename T = int> struct A {}; @@ -41,4 +42,5 @@ G<> g; // expected-error {{default argum H<> h; // expected-error {{default argument of 'H' must be imported from module 'X.A' before it is required}} // expected-note@a.h:8 {{default argument declared here}} I<> i; +L<> *l; END _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits