summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-04-11 08:28:14 +0000
committerChris Lattner <sabre@nondot.org>2010-04-11 08:28:14 +0000
commita36ec4243bea51afe39c9d25206fe26dd30d748c (patch)
tree2ecb63e698763bc8137a6defde656d1ba0f4fcaf /clang/lib/Sema
parent90c58faea6559a237ea26900a2494936b50eaa5a (diff)
downloadbcm5719-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.h12
-rw-r--r--clang/lib/Sema/SemaExpr.cpp20
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp84
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() ||
OpenPOWER on IntegriCloud