summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaOverload.cpp21
-rw-r--r--clang/test/SemaCXX/cxx1y-deduced-return-type.cpp34
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>();
+
+}
}
OpenPOWER on IntegriCloud