Diagnose attempting to assign to a sub-structure of an ivar

using objective-c property. (fixes radar 7449707)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91474 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2009-12-15 23:59:41 +00:00
Родитель 28172a27c0
Коммит 2514a30920
5 изменённых файлов: 43 добавлений и 6 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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">;

Просмотреть файл

@ -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:

Просмотреть файл

@ -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;

Просмотреть файл

@ -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}}
}