diff options
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7461e635c6b..98348d6efc9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -922,11 +922,21 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { return BinOp->getRHS()->isLvalue(Ctx); // C++ [expr.mptr.oper]p6 - if ((BinOp->getOpcode() == BinaryOperator::PtrMemD || - BinOp->getOpcode() == BinaryOperator::PtrMemI) && + // The result of a .* expression is an lvalue only if its first operand is + // an lvalue and its second operand is a pointer to data member. + if (BinOp->getOpcode() == BinaryOperator::PtrMemD && !BinOp->getType()->isFunctionType()) return BinOp->getLHS()->isLvalue(Ctx); + // The result of an ->* expression is an lvalue only if its second operand + // is a pointer to data member. + if (BinOp->getOpcode() == BinaryOperator::PtrMemI && + !BinOp->getType()->isFunctionType()) { + QualType Ty = BinOp->getRHS()->getType(); + if (Ty->isMemberPointerType() && !Ty->isMemberFunctionPointerType()) + return LV_Valid; + } + if (!BinOp->isAssignmentOp()) return LV_InvalidExpression; |