[cfe-commits] r122294 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp test/SemaObjC/special-dep-unavail-warning.m

Fariborz Jahanian fjahanian at apple.com
Mon Dec 20 16:44:01 PST 2010


Author: fjahanian
Date: Mon Dec 20 18:44:01 2010
New Revision: 122294

URL: http://llvm.org/viewvc/llvm-project?rev=122294&view=rev
Log:
Warn when message is sent to receiver of
unknown type and there is a possibility that
at runtime method is resolved to a deprecated or 
unavailable method.  Addreses // rdar://8769853

Added:
    cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=122294&r1=122293&r2=122294&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Dec 20 18:44:01 2010
@@ -1878,10 +1878,15 @@
     InGroup<DeprecatedDeclarations>;
 def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
     InGroup<DeprecatedDeclarations>;
+def warn_deprecated_fwdclass_message : Warning<
+    "%0 maybe deprecated because receiver type is unknown">,
+    InGroup<DeprecatedDeclarations>;
 def err_unavailable : Error<"%0 is unavailable">;
 def err_unavailable_message : Error<"%0 is unavailable: %1">;
+def warn_unavailable_fwdclass_message : Warning<
+    "%0 maybe unavailable because receiver type is unknown">;
 def note_unavailable_here : Note<
-  "function has been explicitly marked %select{unavailable|deleted}0 here">;
+  "function has been explicitly marked %select{unavailable|deleted|deprecated}0 here">;
 def warn_not_enough_argument : Warning<
   "not enough variable arguments in %0 declaration to fit a sentinel">;
 def warn_missing_sentinel : Warning <

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=122294&r1=122293&r2=122294&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Dec 20 18:44:01 2010
@@ -1704,14 +1704,15 @@
   ParsingDeclStackState PushParsingDeclaration();
   void PopParsingDeclaration(ParsingDeclStackState S, Decl *D);
   void EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
-                              SourceLocation Loc);
+                              SourceLocation Loc, bool UnkownObjCClass=false);
 
   void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
 
   //===--------------------------------------------------------------------===//
   // Expression Parsing Callbacks: SemaExpr.cpp.
 
-  bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc);
+  bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, 
+                         bool UnkownObjCClass=false);
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
                                         ObjCMethodDecl *Getter,
                                         SourceLocation Loc);

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=122294&r1=122293&r2=122294&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Dec 20 18:44:01 2010
@@ -2903,7 +2903,8 @@
 }
 
 void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
-                                  SourceLocation Loc) {
+                                  SourceLocation Loc,
+                                  bool UnkownObjCClass) {
   // Delay if we're currently parsing a declaration.
   if (ParsingDeclDepth) {
     DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D, 
@@ -2917,6 +2918,10 @@
   if (!Message.empty())
     Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 
                                              << Message;
-  else
-    Diag(Loc, diag::warn_deprecated) << D->getDeclName();
+  else {
+    if (!UnkownObjCClass)
+      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
+    else
+      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
+  }
 }

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=122294&r1=122293&r2=122294&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Dec 20 18:44:01 2010
@@ -1302,7 +1302,21 @@
   // signature.
   for (ObjCMethodList *List = &Entry; List; List = List->Next)
     if (MatchTwoMethodDeclarations(Method, List->Method)) {
-      List->Method->setDefined(impl);
+      ObjCMethodDecl *PrevObjCMethod = List->Method;
+      PrevObjCMethod->setDefined(impl);
+      // If a method is deprecated, push it in the global pool.
+      // This is used for better diagnostics.
+      if (Method->getAttr<DeprecatedAttr>()) {
+        if (!PrevObjCMethod->getAttr<DeprecatedAttr>())
+          List->Method = Method;
+      }
+      // If new method is unavailable, push it into global pool
+      // unless previous one is deprecated.
+      if (Method->getAttr<UnavailableAttr>()) {
+        if (!PrevObjCMethod->getAttr<UnavailableAttr>() &&
+            !PrevObjCMethod->getAttr<DeprecatedAttr>())
+          List->Method = Method;
+      }
       return;
     }
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=122294&r1=122293&r2=122294&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Dec 20 18:44:01 2010
@@ -49,13 +49,14 @@
 /// used, or produce an error (and return true) if a C++0x deleted
 /// function is being used.
 ///
-/// If IgnoreDeprecated is set to true, this should not want about deprecated
+/// If IgnoreDeprecated is set to true, this should not warn about deprecated
 /// decls.
 ///
 /// \returns true if there was an error (this declaration cannot be
 /// referenced), false otherwise.
 ///
-bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
+bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
+                             bool UnkownObjCClass) {
   if (getLangOptions().CPlusPlus && isa<FunctionDecl>(D)) {
     // If there were any diagnostics suppressed by template argument deduction,
     // emit them now.
@@ -76,13 +77,18 @@
 
   // See if the decl is deprecated.
   if (const DeprecatedAttr *DA = D->getAttr<DeprecatedAttr>())
-    EmitDeprecationWarning(D, DA->getMessage(), Loc);
+    EmitDeprecationWarning(D, DA->getMessage(), Loc, UnkownObjCClass);
 
   // See if the decl is unavailable
   if (const UnavailableAttr *UA = D->getAttr<UnavailableAttr>()) {
-    if (UA->getMessage().empty())
-      Diag(Loc, diag::err_unavailable) << D->getDeclName();
-    else
+    if (UA->getMessage().empty()) {
+      if (!UnkownObjCClass)
+        Diag(Loc, diag::err_unavailable) << D->getDeclName();
+      else
+        Diag(Loc, diag::warn_unavailable_fwdclass_message) 
+             << D->getDeclName();
+    }
+    else 
       Diag(Loc, diag::err_unavailable_message) 
         << D->getDeclName() << UA->getMessage();
     Diag(D->getLocation(), diag::note_unavailable_here) << 0;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=122294&r1=122293&r2=122294&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Dec 20 18:44:01 2010
@@ -1023,6 +1023,7 @@
               break;
           }
         }
+        bool forwardClass = false;
         if (!Method) {
           // If we have implementations in scope, check "private" methods.
           Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
@@ -1033,14 +1034,15 @@
             // compatibility. FIXME: should we deviate??
             if (OCIType->qual_empty()) {
               Method = LookupInstanceMethodInGlobalPool(Sel,
-                                                 SourceRange(LBracLoc, RBracLoc)); 
-              if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
+                                                 SourceRange(LBracLoc, RBracLoc));
+              forwardClass = OCIType->getInterfaceDecl()->isForwardDecl();
+              if (Method && !forwardClass)
                 Diag(Loc, diag::warn_maynot_respond)
                   << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
             }
           }
         }
-        if (Method && DiagnoseUseOfDecl(Method, Loc))
+        if (Method && DiagnoseUseOfDecl(Method, Loc, forwardClass))
           return ExprError();
       } else if (!Context.getObjCIdType().isNull() &&
                  (ReceiverType->isPointerType() || 

Added: cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m?rev=122294&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m (added)
+++ cfe/trunk/test/SemaObjC/special-dep-unavail-warning.m Mon Dec 20 18:44:01 2010
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar://8769853
+
+ at interface B
+- (void) depInA;
+- (void) unavailMeth __attribute__((unavailable)); // expected-note {{function has been explicitly marked unavailable here}}
+- (void) depInA1 __attribute__((deprecated));
+- (void) unavailMeth1;
+- (void) depInA2 __attribute__((deprecated));
+- (void) unavailMeth2 __attribute__((unavailable)); // expected-note {{function has been explicitly marked unavailable here}}
+- (void) depunavailInA;
+- (void) depunavailInA1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{function has been explicitly marked unavailable here}}
+- (void)FuzzyMeth __attribute__((deprecated));
+- (void)FuzzyMeth1 __attribute__((unavailable));
+ at end
+
+ at interface A
+- (void) unavailMeth1 __attribute__((unavailable)); // expected-note {{function has been explicitly marked unavailable here}}
+- (void) depInA __attribute__((deprecated));
+- (void) depInA2 __attribute__((deprecated));
+- (void) depInA1;
+- (void) unavailMeth2 __attribute__((unavailable)); 
+- (void) depunavailInA __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{function has been explicitly marked unavailable here}}
+- (void) depunavailInA1;
+- (void)FuzzyMeth __attribute__((unavailable));
+- (void)FuzzyMeth1 __attribute__((deprecated));
+ at end
+
+
+ at class C;
+
+void test(C *c) {
+  [c depInA]; // expected-warning {{'depInA' maybe deprecated because receiver type is unknown}}
+  [c unavailMeth]; // expected-warning {{'unavailMeth' maybe unavailable because receiver type is unknown}}
+  [c depInA1]; // expected-warning {{'depInA1' maybe deprecated because receiver type is unknown}}
+  [c unavailMeth1]; // expected-warning {{'unavailMeth1' maybe unavailable because receiver type is unknown}}
+  [c depInA2]; // expected-warning {{'depInA2' maybe deprecated because receiver type is unknown}}
+  [c unavailMeth2]; // expected-warning {{'unavailMeth2' maybe unavailable because receiver type is unknown}}
+  [c depunavailInA]; // expected-warning {{'depunavailInA' maybe deprecated because receiver type is unknown}} \
+                     // expected-warning {{'depunavailInA' maybe unavailable because receiver type is unknown}} 
+  [c depunavailInA1]; // expected-warning {{'depunavailInA1' maybe deprecated because receiver type is unknown}} \
+                      // expected-warning {{'depunavailInA1' maybe unavailable because receiver type is unknown}}
+  [c FuzzyMeth];      // expected-warning {{'FuzzyMeth' maybe deprecated because receiver type is unknown}}
+  [c FuzzyMeth1]; // expected-warning {{'FuzzyMeth1' maybe deprecated because receiver type is unknown}}
+
+}
+





More information about the cfe-commits mailing list