aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-12-04 03:47:34 +0000
committerJohn McCall <rjmccall@apple.com>2010-12-04 03:47:34 +0000
commitf6a1648197562e0b133440d612d9af297d0a86cc (patch)
tree10c1ff179182b53e5f8eb356b7fe1ace0c7dab41 /lib/Sema/SemaExprCXX.cpp
parente68b9842d2d6adc2c72c81c845a2c68e58d9d3a4 (diff)
Although we currently have explicit lvalue-to-rvalue conversions, they're
not actually frequently used, because ImpCastExprToType only creates a node if the types differ. So explicitly create an ICE in the lvalue-to-rvalue conversion code in DefaultFunctionArrayLvalueConversion() as well as several other new places, and consistently deal with the consequences throughout the compiler. In addition, introduce a new cast kind for loading an ObjCProperty l-value, and make sure we emit those nodes whenever an ObjCProperty l-value appears that's not on the LHS of an assignment operator. This breaks a couple of rewriter tests, which I've x-failed until future development occurs on the rewriter. Ted Kremenek kindly contributed the analyzer workarounds in this patch. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp62
1 files changed, 47 insertions, 15 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index fceb542c79..965328615d 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1845,10 +1845,21 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
// Perform the first implicit conversion.
switch (SCS.First) {
case ICK_Identity:
- case ICK_Lvalue_To_Rvalue:
// Nothing to do.
break;
+ case ICK_Lvalue_To_Rvalue:
+ // Should this get its own ICK?
+ if (From->getObjectKind() == OK_ObjCProperty) {
+ ConvertPropertyForRValue(From);
+ if (!From->isRValue()) break;
+ }
+
+ FromType = FromType.getUnqualifiedType();
+ From = ImplicitCastExpr::Create(Context, FromType, CK_LValueToRValue,
+ From, 0, VK_RValue);
+ break;
+
case ICK_Array_To_Pointer:
FromType = Context.getArrayDecayedType(FromType);
ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay);
@@ -2746,14 +2757,14 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// The operands have class type. Make a temporary copy.
InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
ExprResult LHSCopy = PerformCopyInitialization(Entity,
- SourceLocation(),
- Owned(LHS));
+ SourceLocation(),
+ Owned(LHS));
if (LHSCopy.isInvalid())
return QualType();
ExprResult RHSCopy = PerformCopyInitialization(Entity,
- SourceLocation(),
- Owned(RHS));
+ SourceLocation(),
+ Owned(RHS));
if (RHSCopy.isInvalid())
return QualType();
@@ -3512,21 +3523,42 @@ ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen);
}
-ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
- if (!FullExpr) return ExprError();
-
+/// Perform the conversions required for an expression used in a
+/// context that ignores the result.
+void Sema::IgnoredValueConversions(Expr *&E) {
// C99 6.3.2.1:
// [Except in specific positions,] an lvalue that does not have
// array type is converted to the value stored in the
// designated object (and is no longer an lvalue).
- // This rule does not apply in C++; however, in ObjC++, we do want
- // to do lvalue-to-rvalue conversion on top-level ObjCProperty
- // l-values.
- if (!FullExpr->isRValue() &&
- (!getLangOptions().CPlusPlus ||
- FullExpr->getObjectKind() == OK_ObjCProperty))
- DefaultFunctionArrayLvalueConversion(FullExpr);
+ if (E->isRValue()) return;
+
+ // We always want to do this on ObjC property references.
+ if (E->getObjectKind() == OK_ObjCProperty) {
+ ConvertPropertyForRValue(E);
+ if (E->isRValue()) return;
+ }
+
+ // Otherwise, this rule does not apply in C++, at least not for the moment.
+ if (getLangOptions().CPlusPlus) return;
+
+ // GCC seems to also exclude expressions of incomplete enum type.
+ if (const EnumType *T = E->getType()->getAs<EnumType>()) {
+ if (!T->getDecl()->isComplete()) {
+ // FIXME: stupid workaround for a codegen bug!
+ ImpCastExprToType(E, Context.VoidTy, CK_ToVoid);
+ return;
+ }
+ }
+
+ DefaultFunctionArrayLvalueConversion(E);
+ RequireCompleteType(E->getExprLoc(), E->getType(),
+ diag::err_incomplete_type);
+}
+
+ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
+ if (!FullExpr) return ExprError();
+ IgnoredValueConversions(FullExpr);
CheckImplicitConversions(FullExpr);
return MaybeCreateCXXExprWithTemporaries(FullExpr);
}