[cfe-commits] r128348 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/ExprClassification.cpp lib/Sema/SemaExpr.cpp test/SemaObjC/assign-rvalue-message.m
Fariborz Jahanian
fjahanian at apple.com
Sat Mar 26 12:48:31 PDT 2011
Author: fjahanian
Date: Sat Mar 26 14:48:30 2011
New Revision: 128348
URL: http://llvm.org/viewvc/llvm-project?rev=128348&view=rev
Log:
More coherent diagnostic attempting to assign to a member of a const object returned
from an objective-c message: // rdar://9005189
Added:
cfe/trunk/test/SemaObjC/assign-rvalue-message.m
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/ExprClassification.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=128348&r1=128347&r2=128348&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Mar 26 14:48:30 2011
@@ -173,6 +173,7 @@
LV_IncompleteVoidType,
LV_DuplicateVectorComponents,
LV_InvalidExpression,
+ LV_InvalidMessageExpression,
LV_MemberFunction,
LV_SubObjCPropertySetting,
LV_ClassTemporary
@@ -204,6 +205,7 @@
MLV_NoSetterProperty,
MLV_MemberFunction,
MLV_SubObjCPropertySetting,
+ MLV_InvalidMessageExpression,
MLV_ClassTemporary
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
@@ -223,6 +225,7 @@
CL_MemberFunction, // An expression referring to a member function
CL_SubObjCPropertySetting,
CL_ClassTemporary, // A prvalue of class type
+ CL_ObjCMessageRValue, // ObjC message is an rvalue
CL_PRValue // A prvalue for any other reason, of any other type
};
/// \brief The results of modification testing.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=128348&r1=128347&r2=128348&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Mar 26 14:48:30 2011
@@ -2697,6 +2697,8 @@
InGroup<PointerArith>;
def error_readonly_property_assignment : Error<
"assigning to property with 'readonly' attribute not allowed">;
+def error_readonly_message_assignment : Error<
+ "assigning to 'readonly' return result of an objective-c message not allowed">;
def ext_integer_increment_complex : Extension<
"ISO C does not support '++'/'--' on complex integer type %0">;
def ext_integer_complement_complex : Extension<
Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=128348&r1=128347&r2=128348&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Sat Mar 26 14:48:30 2011
@@ -75,6 +75,7 @@
case Cl::CL_MemberFunction:
case Cl::CL_SubObjCPropertySetting:
case Cl::CL_ClassTemporary:
+ case Cl::CL_ObjCMessageRValue:
case Cl::CL_PRValue: assert(getValueKind() == VK_RValue); break;
}
@@ -293,7 +294,8 @@
case Expr::ObjCMessageExprClass:
if (const ObjCMethodDecl *Method =
cast<ObjCMessageExpr>(E)->getMethodDecl()) {
- return ClassifyUnnamed(Ctx, Method->getResultType());
+ Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getResultType());
+ return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind;
}
return Cl::CL_PRValue;
@@ -551,6 +553,7 @@
case Cl::CL_MemberFunction: return LV_MemberFunction;
case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting;
case Cl::CL_ClassTemporary: return LV_ClassTemporary;
+ case Cl::CL_ObjCMessageRValue: return LV_InvalidMessageExpression;
case Cl::CL_PRValue: return LV_InvalidExpression;
}
llvm_unreachable("Unhandled kind");
@@ -569,6 +572,7 @@
case Cl::CL_MemberFunction: return MLV_MemberFunction;
case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
case Cl::CL_ClassTemporary: return MLV_ClassTemporary;
+ case Cl::CL_ObjCMessageRValue: return MLV_InvalidMessageExpression;
case Cl::CL_PRValue:
return VC.getModifiable() == Cl::CM_LValueCast ?
MLV_LValueCast : MLV_InvalidExpression;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=128348&r1=128347&r2=128348&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Mar 26 14:48:30 2011
@@ -7378,6 +7378,20 @@
return false;
}
+static bool IsReadonlyMessage(Expr *E, Sema &S) {
+ if (E->getStmtClass() != Expr::MemberExprClass)
+ return false;
+ const MemberExpr *ME = cast<MemberExpr>(E);
+ NamedDecl *Member = ME->getMemberDecl();
+ if (isa<FieldDecl>(Member)) {
+ Expr *Base = ME->getBase()->IgnoreParenImpCasts();
+ if (Base->getStmtClass() != Expr::ObjCMessageExprClass)
+ return false;
+ return cast<ObjCMessageExpr>(Base)->getMethodDecl() != 0;
+ }
+ return false;
+}
+
/// CheckForModifiableLvalue - Verify that E is a modifiable lvalue. If not,
/// emit an error and return true. If so, return false.
static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
@@ -7386,6 +7400,8 @@
&Loc);
if (IsLV == Expr::MLV_Valid && IsReadonlyProperty(E, S))
IsLV = Expr::MLV_ReadonlyProperty;
+ else if (IsLV == Expr::MLV_ClassTemporary && IsReadonlyMessage(E, S))
+ IsLV = Expr::MLV_InvalidMessageExpression;
if (IsLV == Expr::MLV_Valid)
return false;
@@ -7428,6 +7444,9 @@
case Expr::MLV_NoSetterProperty:
Diag = diag::error_nosetter_property_assignment;
break;
+ case Expr::MLV_InvalidMessageExpression:
+ Diag = diag::error_readonly_message_assignment;
+ break;
case Expr::MLV_SubObjCPropertySetting:
Diag = diag::error_no_subobject_property_setting;
break;
@@ -7812,7 +7831,7 @@
ValueDecl *dcl = getPrimaryDecl(op);
Expr::LValueClassification lval = op->ClassifyLValue(S.Context);
- if (lval == Expr::LV_ClassTemporary) {
+ if (lval == Expr::LV_ClassTemporary) {
bool sfinae = S.isSFINAEContext();
S.Diag(OpLoc, sfinae ? diag::err_typecheck_addrof_class_temporary
: diag::ext_typecheck_addrof_class_temporary)
Added: cfe/trunk/test/SemaObjC/assign-rvalue-message.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/assign-rvalue-message.m?rev=128348&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/assign-rvalue-message.m (added)
+++ cfe/trunk/test/SemaObjC/assign-rvalue-message.m Sat Mar 26 14:48:30 2011
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -fobjc-nonfragile-abi %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -fobjc-nonfragile-abi %s
+// rdar://9005189
+
+ at interface Foo
+ at end
+
+struct Bar {
+ int x;
+};
+
+ at implementation Foo {
+ struct Bar bar;
+}
+
+- (const struct Bar)bar {
+ return bar;
+}
+
+- (void)baz {
+ bar.x = 0;
+ [self bar].x = 10; // expected-error {{assigning to 'readonly' return result of an objective-c message not allowed}}
+}
+ at end
More information about the cfe-commits
mailing list