diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-02-16 21:39:57 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-02-16 21:39:57 +0000 |
| commit | b154fdc9749aa09769577cd862193791a98d300e (patch) | |
| tree | af79623b54dfe42c268b4b59ba7cdf1e530b8ec0 /clang/lib/AST/Expr.cpp | |
| parent | 7c7cfbbc380120ade2c03d1af74c7df60d1052b0 (diff) | |
| download | bcm5719-llvm-b154fdc9749aa09769577cd862193791a98d300e.tar.gz bcm5719-llvm-b154fdc9749aa09769577cd862193791a98d300e.zip | |
Introduce a new kind of failed result for isLvalue/isModifiableLvalue
which describes temporary objects of class type in C++. Use this to
provide a more-specific, remappable diagnostic when takin the address
of such a temporary.
llvm-svn: 96396
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 4cb0aa4560d..fac65064c07 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1120,8 +1120,15 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { return LV_Valid; break; case ImplicitCastExprClass: - return cast<ImplicitCastExpr>(this)->isLvalueCast()? LV_Valid - : LV_InvalidExpression; + if (cast<ImplicitCastExpr>(this)->isLvalueCast()) + return LV_Valid; + + // If this is a conversion to a class temporary, make a note of + // that. + if (Ctx.getLangOptions().CPlusPlus && getType()->isRecordType()) + return LV_ClassTemporary; + + break; case ParenExprClass: // C99 6.5.1p5 return cast<ParenExpr>(this)->getSubExpr()->isLvalue(Ctx); case BinaryOperatorClass: @@ -1171,9 +1178,15 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { if (ReturnType->isLValueReferenceType()) return LV_Valid; + // If the function is returning a class temporary, make a note of + // that. + if (Ctx.getLangOptions().CPlusPlus && ReturnType->isRecordType()) + return LV_ClassTemporary; + break; } case CompoundLiteralExprClass: // C99 6.5.2.5p5 + // FIXME: Is this what we want in C++? return LV_Valid; case ChooseExprClass: // __builtin_choose_expr is an lvalue if the selected operand is. @@ -1207,6 +1220,13 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { if (cast<ExplicitCastExpr>(this)->getTypeAsWritten()-> isLValueReferenceType()) return LV_Valid; + + // If this is a conversion to a class temporary, make a note of + // that. + if (Ctx.getLangOptions().CPlusPlus && + cast<ExplicitCastExpr>(this)->getTypeAsWritten()->isRecordType()) + return LV_ClassTemporary; + break; case CXXTypeidExprClass: // C++ 5.2.8p1: The result of a typeid expression is an lvalue of ... @@ -1253,6 +1273,11 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const { return LV_Valid; break; + case Expr::CXXConstructExprClass: + case Expr::CXXTemporaryObjectExprClass: + case Expr::CXXZeroInitValueExprClass: + return LV_ClassTemporary; + default: break; } @@ -1296,6 +1321,8 @@ Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const { case LV_SubObjCPropertySetting: return MLV_SubObjCPropertySetting; case LV_SubObjCPropertyGetterSetting: return MLV_SubObjCPropertyGetterSetting; + case LV_ClassTemporary: + return MLV_ClassTemporary; } // The following is illegal: |

