aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-01-11 15:56:56 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-01-11 15:56:56 +0000
commite27d87ff27b26e5886cf6472271d3b5e18ec3d87 (patch)
tree902c4ac050b08c2bfb37ae8d59db052a6a1f2c0e /lib
parent951b334069f77c0af424e5ea15b75f4ee17b4583 (diff)
Make Clang complain about taking the address of an unqualified member function. Fixes PR5985.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93150 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaExpr.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f131109833..bf9d099e56 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5872,7 +5872,22 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
NamedDecl *dcl = getPrimaryDecl(op);
Expr::isLvalueResult lval = op->isLvalue(Context);
- if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
+ MemberExpr *ME = dyn_cast<MemberExpr>(op);
+ if (lval == Expr::LV_MemberFunction && ME &&
+ isa<CXXMethodDecl>(ME->getMemberDecl())) {
+ ValueDecl *dcl = cast<MemberExpr>(op)->getMemberDecl();
+ // &f where f is a member of the current object, or &o.f, or &p->f
+ // All these are not allowed, and we need to catch them before the dcl
+ // branch of the if, below.
+ Diag(OpLoc, diag::err_unqualified_pointer_member_function)
+ << dcl;
+ // FIXME: Improve this diagnostic and provide a fixit.
+
+ // Now recover by acting as if the function had been accessed qualified.
+ return Context.getMemberPointerType(op->getType(),
+ Context.getTypeDeclType(cast<RecordDecl>(dcl->getDeclContext()))
+ .getTypePtr());
+ } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
// C99 6.5.3.2p1
// The operand must be either an l-value or a function designator
if (!op->getType()->isFunctionType()) {