aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaExpr.cpp23
-rw-r--r--test/SemaObjC/ivar-lookup-resolution-builtin.m40
3 files changed, 60 insertions, 6 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index d06cecc467..bc139c19a8 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1481,7 +1481,8 @@ public:
OwningExprResult LookupInObjCMethod(LookupResult &R,
Scope *S,
- IdentifierInfo *II);
+ IdentifierInfo *II,
+ bool AllowBuiltinCreation=false);
OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
DeclarationName Name,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index c71fd98aa0..f3093c1bad 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1033,12 +1033,13 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
// Just re-use the lookup done by isTemplateName.
DecomposeTemplateName(R, Id);
} else {
- LookupParsedName(R, S, &SS, true);
+ bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+ LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
// If this reference is in an Objective-C method, then we need to do
// some special Objective-C lookup, too.
- if (!SS.isSet() && II && getCurMethodDecl()) {
- OwningExprResult E(LookupInObjCMethod(R, S, II));
+ if (IvarLookupFollowUp) {
+ OwningExprResult E(LookupInObjCMethod(R, S, II, true));
if (E.isInvalid())
return ExprError();
@@ -1218,7 +1219,8 @@ Sema::BuildQualifiedDeclarationNameExpr(const CXXScopeSpec &SS,
/// Returns a null sentinel to indicate trivial success.
Sema::OwningExprResult
Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
- IdentifierInfo *II) {
+ IdentifierInfo *II,
+ bool AllowBuiltinCreation) {
SourceLocation Loc = Lookup.getNameLoc();
// There are two cases to handle here. 1) scoped lookup could have failed,
@@ -1299,7 +1301,18 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
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()) {
+ if (!(getLangOptions().CPlusPlus &&
+ Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))) {
+ NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
+ S, Lookup.isForRedeclaration(),
+ Lookup.getNameLoc());
+ if (D) Lookup.addDecl(D);
+ }
+ }
+ }
// Sentinel value saying that we didn't do anything special.
return Owned((Expr*) 0);
}
diff --git a/test/SemaObjC/ivar-lookup-resolution-builtin.m b/test/SemaObjC/ivar-lookup-resolution-builtin.m
new file mode 100644
index 0000000000..2e90e8e044
--- /dev/null
+++ b/test/SemaObjC/ivar-lookup-resolution-builtin.m
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// pr5986
+
+@interface Test {
+ int index;
+}
+- (int) index;
++ (int) ClassMethod;
+@end
+
+@implementation Test
+- (int) index
+{
+ return index;
+}
++ (int) ClassMethod
+{
+ return index; // expected-error {{instance variable 'index' accessed in class method}}
+}
+@end
+
+@interface Test1 {
+}
+- (int) InstMethod;
++ (int) ClassMethod;
+@end
+
+@implementation Test1
+- (int) InstMethod
+{
+ return index; // expected-warning {{implicitly declaring C library function 'index'}} \
+ // expected-note {{please include the header <strings.h> or explicitly provide a declaration for 'index'}} \
+ // expected-warning {{incompatible pointer to integer conversion returning}}
+}
++ (int) ClassMethod
+{
+ return index; // expected-warning {{incompatible pointer to integer conversion returning}}
+}
+@end
+