r274076 - ObjC Class Property: diagnostics when accessing a class property using instance.
Manman Ren via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 28 16:01:49 PDT 2016
Author: mren
Date: Tue Jun 28 18:01:49 2016
New Revision: 274076
URL: http://llvm.org/viewvc/llvm-project?rev=274076&view=rev
Log:
ObjC Class Property: diagnostics when accessing a class property using instance.
When a class property is accessed with an object instance, before this commit,
we try to apply a typo correction of the same property:
property 'c' not found on object of type 'A *'; did you mean 'c'?
With this commit, we correctly emit a diagnostics:
property 'c' is a class property; did you mean to access it with class 'A'?
rdar://26866973
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/FixIt/fixit-objc.m
cfe/trunk/test/SemaObjC/objc-class-property.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=274076&r1=274075&r2=274076&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 28 18:01:49 2016
@@ -7761,6 +7761,8 @@ def err_typecheck_member_reference_ivar_
"%0 does not have a member named %1; did you mean %2?">;
def err_property_not_found_suggest : Error<
"property %0 not found on object of type %1; did you mean %2?">;
+def err_class_property_found : Error<
+ "property %0 is a class property; did you mean to access it with class '%1'?">;
def err_ivar_access_using_property_syntax_suggest : Error<
"property %0 not found on object of type %1; did you mean to access instance variable %2?">;
def warn_property_access_suggest : Warning<
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=274076&r1=274075&r2=274076&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jun 28 18:01:49 2016
@@ -1817,7 +1817,7 @@ HandleExprPropertyRefExpr(const ObjCObje
Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
- // May be founf in property's qualified list.
+ // May be found in property's qualified list.
if (!Getter)
Getter = LookupMethodInQualifiedType(Sel, OPT, true);
@@ -1837,7 +1837,7 @@ HandleExprPropertyRefExpr(const ObjCObje
PP.getSelectorTable(), Member);
ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
- // May be founf in property's qualified list.
+ // May be found in property's qualified list.
if (!Setter)
Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
@@ -1885,12 +1885,29 @@ HandleExprPropertyRefExpr(const ObjCObje
LookupOrdinaryName, nullptr, nullptr,
llvm::make_unique<DeclFilterCCC<ObjCPropertyDecl>>(),
CTK_ErrorRecovery, IFace, false, OPT)) {
- diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest)
- << MemberName << QualType(OPT, 0));
DeclarationName TypoResult = Corrected.getCorrection();
- return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
- TypoResult, MemberLoc,
- SuperLoc, SuperType, Super);
+ if (TypoResult.isIdentifier() &&
+ TypoResult.getAsIdentifierInfo() == Member) {
+ // There is no need to try the correction if it is the same.
+ NamedDecl *ChosenDecl =
+ Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
+ if (ChosenDecl && isa<ObjCPropertyDecl>(ChosenDecl))
+ if (cast<ObjCPropertyDecl>(ChosenDecl)->isClassProperty()) {
+ // This is a class property, we should not use the instance to
+ // access it.
+ Diag(MemberLoc, diag::err_class_property_found) << MemberName
+ << OPT->getInterfaceDecl()->getName()
+ << FixItHint::CreateReplacement(BaseExpr->getSourceRange(),
+ OPT->getInterfaceDecl()->getName());
+ return ExprError();
+ }
+ } else {
+ diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest)
+ << MemberName << QualType(OPT, 0));
+ return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
+ TypoResult, MemberLoc,
+ SuperLoc, SuperType, Super);
+ }
}
ObjCInterfaceDecl *ClassDeclared;
if (ObjCIvarDecl *Ivar =
Modified: cfe/trunk/test/FixIt/fixit-objc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-objc.m?rev=274076&r1=274075&r2=274076&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-objc.m (original)
+++ cfe/trunk/test/FixIt/fixit-objc.m Tue Jun 28 18:01:49 2016
@@ -67,3 +67,11 @@ void sentinel_test(Sentinel *a) {
sentinel(1, 2, 3); // expected-warning{{missing sentinel in function call}}
[a sentinel:1, 2, 3]; // expected-warning{{missing sentinel in method dispatch}}
}
+
+ at interface A
+ at property (class) int c;
+ at end
+
+int test(A *a) {
+ return a.c; // expected-error {{property 'c' is a class property; did you mean to access it with class 'A'}}
+}
Modified: cfe/trunk/test/SemaObjC/objc-class-property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-class-property.m?rev=274076&r1=274075&r2=274076&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objc-class-property.m (original)
+++ cfe/trunk/test/SemaObjC/objc-class-property.m Tue Jun 28 18:01:49 2016
@@ -33,6 +33,7 @@
int test() {
A *a = [[A alloc] init];
+ a.c; // expected-error {{property 'c' is a class property; did you mean to access it with class 'A'}}
return a.x + A.c;
}
More information about the cfe-commits
mailing list