From: David Majnemer Date: Tue, 11 Jun 2013 03:56:29 +0000 (+0000) Subject: Implement DR61: Address of ambiguous bound methods should be disallowed X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=01e0b1f24af250da37faf953cd82626b360622f6;p=clang Implement DR61: Address of ambiguous bound methods should be disallowed DR61 affirms that expressions containing unresolved member access should be disallowed when performing "address of" operations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183723 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 66598992d7..08e3089094 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8356,7 +8356,15 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, << OrigOp.get()->getSourceRange(); return QualType(); } - + + OverloadExpr *Ovl = cast(OrigOp.get()->IgnoreParens()); + if (isa(Ovl)) + if (!S.ResolveSingleFunctionTemplateSpecialization(Ovl)) { + S.Diag(OpLoc, diag::err_invalid_form_pointer_member_function) + << OrigOp.get()->getSourceRange(); + return QualType(); + } + return S.Context.OverloadTy; } diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp index 5ffc7516f5..01b1b2aea4 100644 --- a/test/CXX/drs/dr0xx.cpp +++ b/test/CXX/drs/dr0xx.cpp @@ -627,7 +627,7 @@ namespace dr60 { // dr60: yes int &n = f(k); } -namespace dr61 { // dr61: no +namespace dr61 { // dr61: yes struct X { static void f(); } x; @@ -638,8 +638,7 @@ namespace dr61 { // dr61: no // This is (presumably) valid, because x.f does not refer to an overloaded // function name. void (*p)() = &x.f; - // FIXME: This should be rejected. - void (*q)() = &y.f; + void (*q)() = &y.f; // expected-error {{cannot create a non-constant pointer to member function}} } namespace dr62 { // dr62: yes diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp index 06cc610740..cd55cc2441 100644 --- a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp @@ -38,6 +38,8 @@ namespace test2 { }; void A::test() { - int (A::*ptr)(int) = &(A::foo); // expected-error {{can't form member pointer of type 'int (test2::A::*)(int)' without '&' and class name}} + // FIXME: The error message in this case is less than clear, we can do + // better. + int (A::*ptr)(int) = &(A::foo); // expected-error {{cannot create a non-constant pointer to member function}} } } diff --git a/test/SemaTemplate/instantiate-overload-candidates.cpp b/test/SemaTemplate/instantiate-overload-candidates.cpp index 7542dbd8ab..6b156a20a4 100644 --- a/test/SemaTemplate/instantiate-overload-candidates.cpp +++ b/test/SemaTemplate/instantiate-overload-candidates.cpp @@ -26,7 +26,7 @@ template struct X { static T f() { T::error; } // expected-error {{has no members}} static T f(bool); }; -void (*p)() = &X().f; // expected-note {{instantiation of}} +void (*p)() = &X::f; // expected-note {{instantiation of}} namespace PR13098 { struct A { diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index 7ec46ab8b0..4c43d45208 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -80,7 +80,7 @@ 7 NAD Can a class with a private virtual base class be derived from? - No + Yes 8 @@ -404,7 +404,7 @@ 61 NAD Address of static member function "&p->f" - No + Yes 62