]> granicus.if.org Git - clang/commitdiff
The meat of this patch is in BuildCXXMemberCalLExpr where we make it use
authorNick Lewycky <nicholas@mxc.ca>
Tue, 12 Feb 2013 08:08:54 +0000 (08:08 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Tue, 12 Feb 2013 08:08:54 +0000 (08:08 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174951 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaOverload.cpp
test/Sema/attr-cleanup.c
test/SemaCXX/attr-deprecated.cpp
test/SemaCXX/undefined-internal.cpp

index 4c8d098158eceab3aee17bf800370b273e896201..97d1ea2cf1d5fdc6fea146267815971c0be57b0f 100644 (file)
@@ -2849,6 +2849,7 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
              CleanupAttr(Attr.getRange(), S.Context, FD,
                          Attr.getAttributeSpellingListIndex()));
   S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
+  S.DiagnoseUseOfDecl(FD, Attr.getParameterLoc());
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on
index f6c6fe118e5658eeaeffbfa47e8eabb9fd8d0179..191683d33dba3eb99335e91c7e1e18fa65264f42 100644 (file)
@@ -11210,7 +11210,9 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {
       if (Method->isPure())
         OdrUse = false;
   }
-  MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E, OdrUse);
+  SourceLocation Loc = E->getMemberLoc().isValid() ?
+                            E->getMemberLoc() : E->getLocStart();
+  MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, OdrUse);
 }
 
 /// \brief Perform marking for a reference to an arbitrary declaration.  It
index 7f24af8be19e870e8e7e82e22dcf601ae9aca184..49d66113dcd6f302216448be495dbc5b9a6fa74c 100644 (file)
@@ -1376,10 +1376,14 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
   }
 
   // Mark the new and delete operators as referenced.
-  if (OperatorNew)
+  if (OperatorNew) {
+    DiagnoseUseOfDecl(OperatorNew, StartLoc);
     MarkFunctionReferenced(StartLoc, OperatorNew);
-  if (OperatorDelete)
+  }
+  if (OperatorDelete) {
+    DiagnoseUseOfDecl(OperatorDelete, StartLoc);
     MarkFunctionReferenced(StartLoc, OperatorDelete);
+  }
 
   // C++0x [expr.new]p17:
   //   If the new expression creates an array of objects of class type,
@@ -5335,12 +5339,12 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
                                VK_RValue, OK_Ordinary);
   if (HadMultipleCandidates)
     ME->setHadMultipleCandidates(true);
+  MarkMemberReferenced(ME);
 
   QualType ResultType = Method->getResultType();
   ExprValueKind VK = Expr::getValueKindForType(ResultType);
   ResultType = ResultType.getNonLValueExprType(Context);
 
-  MarkFunctionReferenced(Exp.get()->getLocStart(), Method);
   CXXMemberCallExpr *CE =
     new (Context) CXXMemberCallExpr(Context, ME, MultiExprArg(), ResultType, VK,
                                     Exp.get()->getLocEnd());
index 0612c73f897070bcb1dbd9c6d7e86643b0e7b06b..1b698724170163826e5ca0ed69c6bf1409ffc4b0 100644 (file)
@@ -3262,10 +3262,9 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
     return Result;
 
   FunctionDecl *Function = Best->Function;
-
-  // This is the overload that will actually be used for the initialization, so
-  // mark it as used.
-  S.MarkFunctionReferenced(DeclLoc, Function);
+  // This is the overload that will be used for this initialization step if we
+  // use this initialization. Mark it as referenced.
+  Function->setReferenced();
 
   // Compute the returned type of the conversion.
   if (isa<CXXConversionDecl>(Function))
@@ -3831,7 +3830,7 @@ static void TryUserDefinedConversion(Sema &S,
   }
 
   FunctionDecl *Function = Best->Function;
-  S.MarkFunctionReferenced(DeclLoc, Function);
+  Function->setReferenced();
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
 
   if (isa<CXXConstructorDecl>(Function)) {
@@ -4609,8 +4608,6 @@ static ExprResult CopyObject(Sema &S,
     return S.Owned(CurInitExpr);
   }
 
-  S.MarkFunctionReferenced(Loc, Constructor);
-
   // Determine the arguments required to actually perform the
   // constructor call (we might have derived-to-base conversions, or
   // the copy constructor may have default arguments).
index 6fa41379703a5342bea7aa3aea683e9a56823de0..c2e0d6f80900e5bd0f592aabb65723113afd8f1a 100644 (file)
@@ -9916,7 +9916,6 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
   switch (OverloadResult) {
   case OR_Success: {
     FunctionDecl *FDecl = (*Best)->Function;
-    SemaRef.MarkFunctionReferenced(Fn->getExprLoc(), FDecl);
     SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
     SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc());
     Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
@@ -10799,7 +10798,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
                                             Best)) {
     case OR_Success:
       Method = cast<CXXMethodDecl>(Best->Function);
-      MarkFunctionReferenced(UnresExpr->getMemberLoc(), Method);
       FoundDecl = Best->FoundDecl;
       CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
       DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc());
index 59ebbfc4599fee2ebb08043c58640cd25815ea59..991822e402e0ce94fd75531aa5197d2f96fa9afe 100644 (file)
@@ -38,3 +38,7 @@ void t4() {
   __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}}
+}
index f3d818a75f35c4a1e62f594922eb2d12623e3233..2d730a8eed330881483b41c5e13c8453c5a0736d 100644 (file)
@@ -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 @@ namespace test6 {
     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}}
+  }
+}
index 40ab33cac42ebe6672f576212ece4e8fc5eca206..e8810adadfa5cd84dbda415b27c2dbbf50b94af8 100644 (file)
@@ -269,3 +269,40 @@ namespace test11 {
     (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}}
+  }
+}