[cfe-commits] r103191 - in /cfe/trunk: lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/attr-deprecated.cpp

John McCall rjmccall at apple.com
Thu May 6 11:15:07 PDT 2010


Author: rjmccall
Date: Thu May  6 13:15:07 2010
New Revision: 103191

URL: http://llvm.org/viewvc/llvm-project?rev=103191&view=rev
Log:
Diagnose deprecated/unavailable functions selected by overload resolution.
Fixes rdar://problem/4232969, or at least the clang parts of it.


Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/attr-deprecated.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=103191&r1=103190&r2=103191&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu May  6 13:15:07 2010
@@ -3517,6 +3517,7 @@
       // Overload resolution determined which function invoke; update the 
       // initializer to reflect that choice.
       S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl);
+      S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation());
       CurInit = S.FixOverloadedFunctionReference(move(CurInit),
                                                  Step->Function.FoundDecl,
                                                  Step->Function.Function);
@@ -3619,6 +3620,7 @@
 
         S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
                                  FoundFn.getAccess());
+        S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
         
         CastKind = CastExpr::CK_ConstructorConversion;
         QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
@@ -3633,6 +3635,7 @@
         IsLvalue = Conversion->getResultType()->isLValueReferenceType();
         S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
                                     FoundFn);
+        S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
         
         // FIXME: Should we move this initialization into a separate 
         // derived-to-base conversion? I believe the answer is "no", because
@@ -3772,6 +3775,7 @@
       // Only check access if all of that succeeded.
       S.CheckConstructorAccess(Loc, Constructor, Entity,
                                Step->Function.FoundDecl.getAccess());
+      S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Loc);
       
       if (shouldBindAsTemporary(Entity))
         CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=103191&r1=103190&r2=103191&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu May  6 13:15:07 2010
@@ -5500,8 +5500,10 @@
     assert(Result != MatchesCopy.end() && "no most-specialized template");
     MarkDeclarationReferenced(From->getLocStart(), *Result);
     FoundResult = Matches[Result - MatchesCopy.begin()].first;
-    if (Complain)
+    if (Complain) {
       CheckUnresolvedAccess(*this, OvlExpr, FoundResult);
+      DiagnoseUseOfDecl(FoundResult, OvlExpr->getNameLoc());
+    }
     return cast<FunctionDecl>(*Result);
   }
 
@@ -5521,8 +5523,10 @@
   if (Matches.size() == 1) {
     MarkDeclarationReferenced(From->getLocStart(), Matches[0].second);
     FoundResult = Matches[0].first;
-    if (Complain)
+    if (Complain) {
       CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first);
+      DiagnoseUseOfDecl(Matches[0].first, OvlExpr->getNameLoc());
+    }
     return cast<FunctionDecl>(Matches[0].second);
   }
 
@@ -5801,6 +5805,7 @@
   case OR_Success: {
     FunctionDecl *FDecl = Best->Function;
     CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
+    DiagnoseUseOfDecl(Best->FoundDecl, ULE->getNameLoc());
     Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
     return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc);
   }
@@ -5945,6 +5950,8 @@
         Input = (Expr *)input.get();
       }
 
+      DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
+
       // Determine the result type
       QualType ResultTy = FnDecl->getResultType().getNonReferenceType();
 
@@ -5958,7 +5965,7 @@
       ExprOwningPtr<CallExpr> TheCall(this,
         new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
                                           Args, NumArgs, ResultTy, OpLoc));
-      
+
       if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
                               FnDecl))
         return ExprError();
@@ -6150,6 +6157,8 @@
           Args[1] = RHS = Arg1.takeAs<Expr>();
         }
 
+        DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
+
         // Determine the result type
         QualType ResultTy
           = FnDecl->getType()->getAs<FunctionType>()->getResultType();
@@ -6286,6 +6295,7 @@
         // operator.
 
         CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl);
+        DiagnoseUseOfDecl(Best->FoundDecl, LLoc);
 
         // Convert the arguments.
         CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
@@ -6452,6 +6462,7 @@
       Method = cast<CXXMethodDecl>(Best->Function);
       FoundDecl = Best->FoundDecl;
       CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
+      DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc());
       break;
 
     case OR_No_Viable_Function:
@@ -6661,6 +6672,7 @@
                          Best->Conversions[0].UserDefined.ConversionFunction);
 
     CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+    DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
 
     // We selected one of the surrogate functions that converts the
     // object parameter to a function pointer. Perform the conversion
@@ -6677,6 +6689,7 @@
   }
 
   CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+  DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
 
   // We found an overloaded operator(). Build a CXXOperatorCallExpr
   // that calls this method, using Object for the implicit object
@@ -6847,6 +6860,7 @@
   }
 
   CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+  DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
 
   // Convert the object parameter.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);

Modified: cfe/trunk/test/SemaCXX/attr-deprecated.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated.cpp?rev=103191&r1=103190&r2=103191&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-deprecated.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-deprecated.cpp Thu May  6 13:15:07 2010
@@ -64,3 +64,129 @@
 void f(D* d) {
   d->f();
 }
+
+
+// Overloaded namespace members.
+namespace test1 {
+  void foo(int) __attribute__((deprecated));
+  void test1() { foo(10); } // expected-warning {{deprecated}}
+  void foo(short) __attribute__((deprecated));
+  void test2(short s) { foo(s); } // expected-warning {{deprecated}}
+  void foo(long);
+  void test3(long l) { foo(l); }
+  struct A {
+    friend void foo(A*) __attribute__((deprecated));
+  };
+  void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
+
+  namespace ns {
+    struct Foo {};
+    void foo(const Foo &f) __attribute__((deprecated));
+  }
+  void test5() {
+    foo(ns::Foo()); // expected-warning {{deprecated}}
+  }
+}
+
+// Overloaded class members.
+namespace test2 {
+  struct A {
+    void foo(int) __attribute__((deprecated));
+    void foo(long);
+    static void bar(int) __attribute__((deprecated));
+    static void bar(long);
+
+    void test2(int i, long l);
+  };
+  void test1(int i, long l) {
+    A a;
+    a.foo(i); // expected-warning {{deprecated}}
+    a.foo(l);
+    a.bar(i); // expected-warning {{deprecated}}
+    a.bar(l);
+    A::bar(i); // expected-warning {{deprecated}}
+    A::bar(l);
+  }
+
+  void A::test2(int i, long l) {
+    foo(i); // expected-warning {{deprecated}}
+    foo(l);
+    bar(i); // expected-warning {{deprecated}}
+    bar(l);
+  }
+}
+
+// Overloaded operators.
+namespace test3 {
+  struct A {
+    void operator*(const A &);
+    void operator*(int) __attribute__((deprecated));
+    void operator-(const A &) const;
+  };
+  void operator+(const A &, const A &);
+  void operator+(const A &, int) __attribute__((deprecated));
+  void operator-(const A &, int) __attribute__((deprecated));
+
+  void test() {
+    A a, b;
+    a + b;
+    a + 1; // expected-warning {{deprecated}}
+    a - b;
+    a - 1; // expected-warning {{deprecated}}
+    a * b;
+    a * 1; // expected-warning {{deprecated}}
+  }
+}
+
+// Overloaded operator call.
+namespace test4 {
+  struct A {
+    typedef void (*intfn)(int);
+    typedef void (*unintfn)(unsigned);
+    operator intfn() __attribute__((deprecated));
+    operator unintfn();
+    void operator ()(A &) __attribute__((deprecated));
+    void operator ()(const A &);
+  };
+
+  void test() {
+    A a;
+    a(1); // expected-warning {{deprecated}}
+    a(1U);
+
+    A &b = a;
+    const A &c = a;
+    a(b); // expected-warning {{deprecated}}
+    a(c);
+  }
+}
+
+namespace test5 {
+  struct A {
+    operator int() __attribute__((deprecated));
+    operator long();
+  };
+  void test1(A a) {
+    int i = a; // expected-warning {{deprecated}}
+    long l = a;
+  }
+
+  void foo(int);
+  void foo(void*);
+  void bar(long);
+  void bar(void*);
+  void test2(A a) {
+    foo(a); // expected-warning {{deprecated}}
+    bar(a);
+  }
+
+  struct B {
+    int myInt;
+    long myLong;
+
+    B(A &a) :
+      myInt(a), // expected-warning {{deprecated}}
+      myLong(a)
+    {}
+  };
+}





More information about the cfe-commits mailing list