diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-04-11 08:28:14 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-04-11 08:28:14 +0000 |
| commit | a36ec4243bea51afe39c9d25206fe26dd30d748c (patch) | |
| tree | 2ecb63e698763bc8137a6defde656d1ba0f4fcaf /clang/lib/Sema | |
| parent | 90c58faea6559a237ea26900a2494936b50eaa5a (diff) | |
| download | bcm5719-llvm-a36ec4243bea51afe39c9d25206fe26dd30d748c.tar.gz bcm5719-llvm-a36ec4243bea51afe39c9d25206fe26dd30d748c.zip | |
fix PR6811 by not parsing 'super' as a magic expression in
LookupInObjCMethod. Doing so allows all sorts of invalid code
to slip through to codegen. This patch does not change the
AST representation of super, though that would now be a natural
thing to do since it can only be in the receiver position and
in the base of a ObjCPropertyRefExpr.
There are still several ugly areas handling super in the parser,
but this is definitely a step in the right direction.
llvm-svn: 100959
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 12 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 84 |
3 files changed, 63 insertions, 53 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index d6476be685f..822e95971c7 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -3845,17 +3845,17 @@ public: ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel, ObjCInterfaceDecl *ClassDecl); - Action::OwningExprResult + OwningExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, DeclarationName MemberName, SourceLocation MemberLoc); - virtual OwningExprResult ActOnClassPropertyRefExpr( - IdentifierInfo &receiverName, - IdentifierInfo &propertyName, - SourceLocation &receiverNameLoc, - SourceLocation &propertyNameLoc); + virtual OwningExprResult + ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, + IdentifierInfo &propertyName, + SourceLocation receiverNameLoc, + SourceLocation propertyNameLoc); // ActOnClassMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c173705be55..54f74d5d6ef 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1233,10 +1233,11 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, /// Returns a null sentinel to indicate trivial success. Sema::OwningExprResult Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, - IdentifierInfo *II, - bool AllowBuiltinCreation) { + IdentifierInfo *II, bool AllowBuiltinCreation) { SourceLocation Loc = Lookup.getNameLoc(); + // FIXME: Stop re-evaluating "getCurMethodDecl". + // There are two cases to handle here. 1) scoped lookup could have failed, // in which case we should look for an ivar. 2) scoped lookup could have // found a decl, but that decl is outside the current instance method (i.e. @@ -1304,17 +1305,6 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, } } - // Needed to implement property "super.method" notation. - if (Lookup.empty() && II->isStr("super")) { - QualType T; - - if (getCurMethodDecl()->isInstanceMethod()) - T = Context.getObjCObjectPointerType(Context.getObjCInterfaceType( - getCurMethodDecl()->getClassInterface())); - else - T = Context.getObjCClassType(); - return Owned(new (Context) ObjCSuperExpr(Loc, T)); - } if (Lookup.empty() && II && AllowBuiltinCreation) { // FIXME. Consolidate this with similar code in LookupName. if (unsigned BuiltinID = II->getBuiltinID()) { @@ -3138,6 +3128,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, return ExprError(Diag(MemberLoc, diag::err_property_not_found) << MemberName << BaseType); } + // Handle Objective-C property access, which is "Obj.property" where Obj is a // pointer to a (potentially qualified) interface type. if (!IsArrow) @@ -3850,9 +3841,6 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, if (castExpr->getType()->isVectorType()) return CheckVectorCast(TyR, castExpr->getType(), castType, Kind); - if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr)) - return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR; - if (isa<ObjCSelectorExpr>(castExpr)) return Diag(castExpr->getLocStart(), diag::err_cast_selector_expr); diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 327e294f36d..9ada985cdca 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -394,20 +394,42 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, -Action::OwningExprResult Sema::ActOnClassPropertyRefExpr( - IdentifierInfo &receiverName, - IdentifierInfo &propertyName, - SourceLocation &receiverNameLoc, - SourceLocation &propertyNameLoc) { +Action::OwningExprResult Sema:: +ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, + IdentifierInfo &propertyName, + SourceLocation receiverNameLoc, + SourceLocation propertyNameLoc) { IdentifierInfo *receiverNamePtr = &receiverName; ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr); - if (!IFace) { - Diag(receiverNameLoc, diag::err_expected_ident_or_lparen); - return ExprError(); + if (IFace == 0) { + // If the "receiver" is 'super' in a method, handle it as an expression-like + // property reference. + if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) + if (receiverNamePtr->isStr("super")) { + if (CurMethod->isInstanceMethod()) { + QualType T = + Context.getObjCInterfaceType(CurMethod->getClassInterface()); + T = Context.getObjCObjectPointerType(T); + Expr *SuperExpr = new (Context) ObjCSuperExpr(receiverNameLoc, T); + + return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(), + SuperExpr, &propertyName, + propertyNameLoc); + } + + // Otherwise, if this is a class method, try dispatching to our + // superclass. + IFace = CurMethod->getClassInterface()->getSuperClass(); + } + + if (IFace == 0) { + Diag(receiverNameLoc, diag::err_expected_ident_or_lparen); + return ExprError(); + } } - // Search for a declared property first. + // Search for a declared property first. Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName); ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel); @@ -468,12 +490,11 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr( // ActOnClassMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). -Sema::ExprResult Sema::ActOnClassMessage( - Scope *S, - IdentifierInfo *receiverName, Selector Sel, - SourceLocation lbrac, SourceLocation receiverLoc, - SourceLocation selectorLoc, SourceLocation rbrac, - ExprTy **Args, unsigned NumArgs) { +Sema::ExprResult Sema:: +ActOnClassMessage(Scope *S, IdentifierInfo *receiverName, Selector Sel, + SourceLocation lbrac, SourceLocation receiverLoc, + SourceLocation selectorLoc, SourceLocation rbrac, + ExprTy **Args, unsigned NumArgs) { assert(receiverName && "missing receiver class name"); Expr **ArgExprs = reinterpret_cast<Expr **>(Args); @@ -481,16 +502,16 @@ Sema::ExprResult Sema::ActOnClassMessage( bool isSuper = false; if (receiverName->isStr("super")) { - if (getCurMethodDecl()) { + if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { isSuper = true; - ObjCInterfaceDecl *OID = getCurMethodDecl()->getClassInterface(); + ObjCInterfaceDecl *OID = CurMethod->getClassInterface(); if (!OID) return Diag(lbrac, diag::error_no_super_class_message) - << getCurMethodDecl()->getDeclName(); + << CurMethod->getDeclName(); ClassDecl = OID->getSuperClass(); if (!ClassDecl) return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName(); - if (getCurMethodDecl()->isInstanceMethod()) { + if (CurMethod->isInstanceMethod()) { QualType superTy = Context.getObjCInterfaceType(ClassDecl); superTy = Context.getObjCObjectPointerType(superTy); ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(), @@ -504,6 +525,11 @@ Sema::ExprResult Sema::ActOnClassMessage( } else { // 'super' has been used outside a method context. If a variable named // 'super' has been declared, redirect. If not, produce a diagnostic. + + // FIXME: + // FIXME: This should be handled in the parser! + // FIXME: + NamedDecl *SuperDecl = LookupSingleName(S, receiverName, LookupOrdinaryName); ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl); @@ -514,17 +540,7 @@ Sema::ExprResult Sema::ActOnClassMessage( return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac, selectorLoc, rbrac, Args, NumArgs); } - else if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(SuperDecl)) { - const ObjCInterfaceType *OCIT; - OCIT = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>(); - if (!OCIT) { - Diag(receiverLoc, diag::err_invalid_receiver_to_message); - return true; - } - ClassDecl = OCIT->getDecl(); - } - else - return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName; + ClassDecl = getObjCInterfaceDecl(receiverName, receiverLoc); } } else ClassDecl = getObjCInterfaceDecl(receiverName, receiverLoc); @@ -548,7 +564,11 @@ Sema::ExprResult Sema::ActOnClassMessage( ClassDecl = OCIT->getDecl(); if (!ClassDecl) { - Diag(receiverLoc, diag::err_invalid_receiver_to_message); + // Give a better error message for invalid use of super. + if (receiverName->isStr("super")) + Diag(receiverLoc, diag::err_invalid_receiver_to_message_super); + else + Diag(receiverLoc, diag::err_invalid_receiver_to_message); return true; } } @@ -616,6 +636,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, QualType ReceiverCType = Context.getCanonicalType(RExpr->getType()).getUnqualifiedType(); +#if 0 // Handle messages to 'super'. if (isa<ObjCSuperExpr>(RExpr)) { ObjCMethodDecl *Method = 0; @@ -643,6 +664,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, Method, lbrac, rbrac, ArgExprs, NumArgs); } +#endif // Handle messages to id. if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() || |

