The meat of this patch is in BuildCXXMemberCalLExpr where we make it use
MarkMemberReferenced instead of marking functions referenced directly. An audit
of callers to MarkFunctionReferenced and DiagnoseUseOfDecl also caused a few
other changes:
 * don't mark functions odr-used when considering them for an initialization
   sequence. Do mark them referenced though.
 * the function nominated by the cleanup attribute should be diagnosed.
 * operator new/delete should be diagnosed when building a 'new' expression.

llvm-svn: 174951
diff --git a/clang/test/Sema/attr-cleanup.c b/clang/test/Sema/attr-cleanup.c
index 59ebbfc..991822e 100644
--- a/clang/test/Sema/attr-cleanup.c
+++ b/clang/test/Sema/attr-cleanup.c
@@ -38,3 +38,7 @@
   __attribute((cleanup(c4))) void* g;
 }
 
+void c5(void*) __attribute__((deprecated));  // expected-note{{'c5' declared here}}
+void t5() {
+  int i __attribute__((cleanup(c5)));  // expected-warning {{'c5' is deprecated}}
+}
diff --git a/clang/test/SemaCXX/attr-deprecated.cpp b/clang/test/SemaCXX/attr-deprecated.cpp
index f3d818a..2d730a8 100644
--- a/clang/test/SemaCXX/attr-deprecated.cpp
+++ b/clang/test/SemaCXX/attr-deprecated.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fexceptions
 class A {
   void f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
   void g(A* a);
@@ -233,3 +233,14 @@
     x = D<int>::d1; // expected-warning {{'d1' is deprecated}}
   }
 }
+
+namespace test7 {
+  struct X {
+    void* operator new(unsigned long) __attribute__((deprecated));  // expected-note{{'operator new' declared here}}
+    void operator delete(void *) __attribute__((deprecated));  // expected-note{{'operator delete' declared here}}
+  };
+
+  void test() {
+    X *x = new X;  // expected-warning{{'operator new' is deprecated}} expected-warning{{'operator delete' is deprecated}}
+  }
+}
diff --git a/clang/test/SemaCXX/undefined-internal.cpp b/clang/test/SemaCXX/undefined-internal.cpp
index 40ab33c..e8810ad 100644
--- a/clang/test/SemaCXX/undefined-internal.cpp
+++ b/clang/test/SemaCXX/undefined-internal.cpp
@@ -269,3 +269,40 @@
     (void)b1->member;  // expected-note {{used here}}
   }
 }
+
+namespace test12 {
+  class T1 {}; class T2 {}; class T3 {}; class T4 {}; class T5 {}; class T6 {};
+  class T7 {};
+
+  namespace {
+    struct Cls {
+      virtual void f(int) = 0;
+      virtual void f(int, double) = 0;
+      void g(int);  // expected-warning {{function 'test12::<anonymous namespace>::Cls::g' has internal linkage but is not defined}}
+      void g(int, double);
+      virtual operator T1() = 0;
+      virtual operator T2() = 0;
+      virtual operator T3&() = 0;
+      operator T4();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T4' has internal linkage but is not defined}}
+      operator T5();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T5' has internal linkage but is not defined}}
+      operator T6&();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator class test12::T6 &' has internal linkage but is not defined}}
+    };
+
+    struct Cls2 {
+      Cls2(T7);  // expected-warning {{function 'test12::<anonymous namespace>::Cls2::Cls2' has internal linkage but is not defined}}
+    };
+  }
+
+  void test(Cls &c) {
+    c.f(7);
+    c.g(7);  // expected-note {{used here}}
+    (void)static_cast<T1>(c);
+    T2 t2 = c;
+    T3 &t3 = c;
+    (void)static_cast<T4>(c); // expected-note {{used here}}
+    T5 t5 = c;  // expected-note {{used here}}
+    T6 &t6 = c;  // expected-note {{used here}}
+
+    Cls2 obj1((T7()));  // expected-note {{used here}}
+  }
+}