[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