diff options
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 21 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1y-deduced-return-type.cpp | 34 |
2 files changed, 52 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index b9983ef0559..5a40b1f8f20 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -43,8 +43,15 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl, SourceLocation Loc = SourceLocation(), const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){ if (S.DiagnoseUseOfDecl(FoundDecl, Loc)) + return ExprError(); + // If FoundDecl is different from Fn (such as if one is a template + // and the other a specialization), make sure DiagnoseUseOfDecl is + // called on both. + // FIXME: This would be more comprehensively addressed by modifying + // DiagnoseUseOfDecl to accept both the FoundDecl and the decl + // being used. + if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc)) return ExprError(); - DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); if (HadMultipleCandidates) @@ -11001,6 +11008,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) return ExprError(); + // If FoundDecl is different from Method (such as if one is a template + // and the other a specialization), make sure DiagnoseUseOfDecl is + // called on both. + // FIXME: This would be more comprehensively addressed by modifying + // DiagnoseUseOfDecl to accept both the FoundDecl and the decl + // being used. + if (Method != FoundDecl.getDecl() && + DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc())) + return ExprError(); break; case OR_No_Viable_Function: @@ -11246,7 +11262,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc)) return ExprError(); - + assert(Conv == Best->FoundDecl.getDecl() && + "Found Decl & conversion-to-functionptr should be same, right?!"); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion // on the object argument, then let ActOnCallExpr finish the job. diff --git a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp index eb6f6aaf9bc..d3067eb411c 100644 --- a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -339,5 +339,37 @@ namespace ExplicitInstantiationDecl { extern template auto f(int); int (*p)(int) = f; } - +namespace MemberTemplatesWithDeduction { + struct M { + template<class T> auto foo(T t) { return t; } + template<class T> auto operator()(T t) const { return t; } + template<class T> static __attribute__((unused)) int static_foo(T) { + return 5; + } + template<class T> operator T() { return T{}; } + operator auto() { return &static_foo<int>; } + }; + struct N : M { + using M::foo; + using M::operator(); + using M::static_foo; + using M::operator auto; + }; + + template <class T> int test() { + int i = T{}.foo(3); + T m = T{}.foo(M{}); + int j = T{}(3); + M m2 = M{}(M{}); + int k = T{}.static_foo(4); + int l = T::static_foo(5); + int l2 = T{}; + struct X { }; + X x = T{}; + return 0; + } + int Minst = test<M>(); + int Ninst = test<N>(); + +} } |

