aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-07-22 23:33:21 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-07-22 23:33:21 +0000
commit69d5624644dad6b5117f8fee8fc4b09427861367 (patch)
tree9f34c77bc6ea823d88c7a9da0bb6e828ea681cdb
parentb92caa5aa6f428ab1bf1a71bea5a35e15c309d8c (diff)
Warn when property ivar lookup finds a global variable
of same name. In nonfragile-abi2, lookup accesses a synthesized ivar. This is a transition warning. Radar 8225011. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109197 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--lib/Sema/SemaExpr.cpp33
-rw-r--r--test/SemaObjC/conflict-nonfragile-abi2.m13
4 files changed, 49 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 033b6c4214..f0c556ce3a 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -135,6 +135,7 @@ def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
def Selector : DiagGroup<"selector">;
+def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">;
def Protocol : DiagGroup<"protocol">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def : DiagGroup<"variadic-macros">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 6fb53189cd..12933ca601 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2492,6 +2492,10 @@ def note_condition_assign_silence : Note<
def warn_value_always_zero : Warning<
"%0 is always %select{zero|false|NULL}1 in this context">;
+def warn_ivar_variable_conflict : Warning<
+ "%0 lookup will access the property ivar in nonfragile-abi2 mode">,
+ InGroup<NonfragileAbi2>;
+
// assignment related diagnostics (also for argument passing, returning, etc).
// In most of these diagnostics the %2 is a value from the
// Sema::AssignmentAction enumeration
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 58bc4f0801..d2f68e0331 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1005,6 +1005,25 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
return true;
}
+static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef,
+ IdentifierInfo *II,
+ SourceLocation NameLoc) {
+ ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+ ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+ if (!IDecl)
+ return 0;
+ ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+ if (!ClassImpDecl)
+ return 0;
+ ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+ if (!property)
+ return 0;
+ if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+ if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ return 0;
+ return property;
+}
+
static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
IdentifierInfo *II,
SourceLocation NameLoc) {
@@ -1077,7 +1096,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
isAddressOfOperand,
TemplateArgs);
}
-
+ bool IvarLookupFollowUp = false;
// Perform the required lookup.
LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
if (TemplateArgs) {
@@ -1090,7 +1109,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false,
MemberOfUnknownSpecialization);
} else {
- bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+ IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
// If this reference is in an Objective-C method, then we need to do
@@ -1151,6 +1170,16 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
assert(!R.empty() || ADL);
if (VarDecl *Var = R.getAsSingle<VarDecl>()) {
+ if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp &&
+ !getLangOptions().ObjCNonFragileABI2) {
+ ObjCPropertyDecl *Property =
+ OkToSynthesizeProvisionalIvar(*this, II, NameLoc);
+ if (Property) {
+ Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName();
+ Diag(Property->getLocation(), diag::note_property_declare);
+ }
+ }
+
// Warn about constructs like:
// if (void *X = foo()) { ... } else { X }.
// In the else block, the pointer is always false.
diff --git a/test/SemaObjC/conflict-nonfragile-abi2.m b/test/SemaObjC/conflict-nonfragile-abi2.m
new file mode 100644
index 0000000000..49cff97ccb
--- /dev/null
+++ b/test/SemaObjC/conflict-nonfragile-abi2.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -verify -fsyntax-only %s
+// rdar : // 8225011
+
+int glob;
+
+@interface I
+@property int glob; // expected-note {{property declared here}}
+@end
+
+@implementation I
+- (int) Meth { return glob; } // expected-warning {{'glob' lookup will access the property ivar in nonfragile-abi2 mode}}
+@synthesize glob;
+@end