]> granicus.if.org Git - clang/commitdiff
Diagnose attempting to assign to a sub-structure of an ivar
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 15 Dec 2009 23:59:41 +0000 (23:59 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 15 Dec 2009 23:59:41 +0000 (23:59 +0000)
using objective-c property. (fixes radar 7449707)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91474 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/Expr.cpp
lib/Sema/SemaExpr.cpp
test/SemaObjC/property-not-lvalue.m [new file with mode: 0644]

index 469598ff372373f767b6ac588abde22272e7d668..6807f2c5a2d80cf7b938300fe01050e13b1020d2 100644 (file)
@@ -156,7 +156,8 @@ public:
     LV_IncompleteVoidType,
     LV_DuplicateVectorComponents,
     LV_InvalidExpression,
-    LV_MemberFunction
+    LV_MemberFunction,
+    LV_SubObjCPropertySetting
   };
   isLvalueResult isLvalue(ASTContext &Ctx) const;
 
@@ -185,7 +186,8 @@ public:
     MLV_NotBlockQualified,
     MLV_ReadonlyProperty,
     MLV_NoSetterProperty,
-    MLV_MemberFunction
+    MLV_MemberFunction,
+    MLV_SubObjCPropertySetting
   };
   isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
                                               SourceLocation *Loc = 0) const;
index d2f2211de8c32a3cf0b24e53ef5943eb5fc4dece..f80cb6a1e465b0df94ab12f3718a0359cd63e381 100644 (file)
@@ -1704,6 +1704,8 @@ def ext_integer_complement_complex : Extension<
   "ISO C does not support '~' for complex conjugation of %0">;
 def error_nosetter_property_assignment : Error<
   "setter method is needed to assign to object using property" " assignment syntax">;
+def error_no_subobject_property_setting : Error<
+  "cannot assign to a sub-structure of an ivar using property" " assignment syntax">;
 
 def ext_freestanding_complex : Extension<
   "complex numbers are an extension in a freestanding C99 implementation">;
index 139e04b2ed5e14c4b2ee387063e3bf98123d2a96..dcf4411d854380f04f7b6d75459b2585a4cb26ba 100644 (file)
@@ -1047,8 +1047,13 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
 
       //   -- If E2 is a non-static data member [...]. If E1 is an
       //      lvalue, then E1.E2 is an lvalue.
-      if (isa<FieldDecl>(Member))
-        return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
+      if (isa<FieldDecl>(Member)) {
+        if (m->isArrow())
+          return LV_Valid;
+        Expr *BaseExp = m->getBase();
+        return (BaseExp->getStmtClass() == ObjCPropertyRefExprClass) ?
+                 LV_SubObjCPropertySetting : BaseExp->isLvalue(Ctx);        
+      }
 
       //   -- If it refers to a static member function [...], then
       //      E1.E2 is an lvalue.
@@ -1065,9 +1070,13 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
         // Not an lvalue.
       return LV_InvalidExpression;
     }
-
+    
     // C99 6.5.2.3p4
-    return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(Ctx);
+    if (m->isArrow())
+      return LV_Valid;
+    Expr *BaseExp = m->getBase();
+    return (BaseExp->getStmtClass() == ObjCPropertyRefExprClass) ?
+             LV_SubObjCPropertySetting : BaseExp->isLvalue(Ctx);
   }
   case UnaryOperatorClass:
     if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Deref)
@@ -1244,6 +1253,7 @@ Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
     }
     return MLV_InvalidExpression;
   case LV_MemberFunction: return MLV_MemberFunction;
+    case LV_SubObjCPropertySetting: return MLV_SubObjCPropertySetting;
   }
 
   // The following is illegal:
index 65c95b36aa0756157ce1a3fde38b37147d60ee9d..12c3a3a2b00744f8c064c6c773cd445979c50a31 100644 (file)
@@ -5573,6 +5573,9 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
   case Expr::MLV_NoSetterProperty:
     Diag = diag::error_nosetter_property_assignment;
     break;
+  case Expr::MLV_SubObjCPropertySetting:
+    Diag = diag::error_no_subobject_property_setting;
+    break;
   }
 
   SourceRange Assign;
diff --git a/test/SemaObjC/property-not-lvalue.m b/test/SemaObjC/property-not-lvalue.m
new file mode 100644 (file)
index 0000000..f1bda09
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct NSSize {
+               int width;
+               struct {
+                 int dim;
+               } inner;
+} NSSize;
+
+@interface Foo  {
+        NSSize _size;
+}
+@property NSSize size;
+@end
+
+void foo() { 
+        Foo *f;
+        f.size.width = 2.2; // expected-error {{cannot assign to a sub-structure of an ivar using property assignment syntax}}
+       f.size.inner.dim = 200; // expected-error {{cannot assign to a sub-structure of an ivar using property assignment syntax}}
+}