From: Eli Friedman Date: Sat, 16 Jan 2010 00:00:48 +0000 (+0000) Subject: Make the AST explicitly represent the cast of the first operand of a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3005efeb131ccddcda9c332c83e49c32349e2aed;p=clang Make the AST explicitly represent the cast of the first operand of a pointer-to-member operator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93592 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 1ad931e541..e4812682a0 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1450,12 +1450,14 @@ QualType Sema::CheckPointerToMemberOperands( // overkill? if (!IsDerivedFrom(LType, Class, Paths) || Paths.isAmbiguous(Context.getCanonicalType(Class))) { - const char *ReplaceStr = isIndirect ? ".*" : "->*"; Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling - << (int)isIndirect << lex->getType() << - CodeModificationHint::CreateReplacement(SourceRange(Loc), ReplaceStr); + << (int)isIndirect << lex->getType(); return QualType(); } + // Cast LHS to type of use. + QualType UseType = isIndirect ? Context.getPointerType(Class) : Class; + bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid; + ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue); } if (isa(rex->IgnoreParens())) { diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 2454ddab77..e1353a72b3 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -139,3 +139,14 @@ namespace PR5940 { void (foo::*ptr)(void) = &foo::baz; } } + +namespace MemberPointerImpCast { + struct A { + int x; + }; + struct B : public A { + }; + void f(B* obj, void (A::*method)()) { + (obj->*method)(); + } +}