Teach CXXUnresolvedConstructExpr when it should be an

lvalue/xvalue/rvalue, rather than just (incorrectly) assuming it's an
lvalue. Fixes PR10285 / <rdar://problem/9743926>.

llvm-svn: 134700
This commit is contained in:
Douglas Gregor 2011-07-08 15:50:43 +00:00
parent 2bb8b26aa8
commit 6336f29669
3 changed files with 27 additions and 2 deletions

View File

@ -725,7 +725,10 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
SourceLocation RParenLoc)
: Expr(CXXUnresolvedConstructExprClass,
Type->getType().getNonReferenceType(),
VK_LValue, OK_Ordinary,
(Type->getType()->isLValueReferenceType() ? VK_LValue
:Type->getType()->isRValueReferenceType()? VK_XValue
:VK_RValue),
OK_Ordinary,
Type->getType()->isDependentType(), true, true,
Type->getType()->containsUnexpandedParameterPack()),
Type(Type),

View File

@ -117,7 +117,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::UnresolvedLookupExprClass:
case Expr::UnresolvedMemberExprClass:
case Expr::CXXDependentScopeMemberExprClass:
case Expr::CXXUnresolvedConstructExprClass:
case Expr::DependentScopeDeclRefExprClass:
// ObjC instance variables are lvalues
// FIXME: ObjC++0x might have different rules
@ -295,6 +294,10 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
if (!Lang.CPlusPlus) return Cl::CL_PRValue;
return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
case Expr::CXXUnresolvedConstructExprClass:
return ClassifyUnnamed(Ctx,
cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
case Expr::BinaryConditionalOperatorClass: {
if (!Lang.CPlusPlus) return Cl::CL_PRValue;
const BinaryConditionalOperator *co = cast<BinaryConditionalOperator>(E);

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
class A
{
public:
A() {}
template <class _F>
explicit A(_F&& __f);
A(A&&) {}
A& operator=(A&&) {return *this;}
};
template <class T>
void f(T t)
{
A a;
a = f(t);
}