]> granicus.if.org Git - clang/commitdiff
Diagnose illegally typed operator new/new[].
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 10 Nov 2009 23:47:18 +0000 (23:47 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 10 Nov 2009 23:47:18 +0000 (23:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86755 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp
test/CodeGenCXX/new-operator-phi.cpp
test/SemaCXX/new-delete.cpp

index 8b76464db34d2bf3e817be2e76b6a81b8b0b2b62..285ae8f70db25987af512009117b7a6ed11a0d99 100644 (file)
@@ -2108,6 +2108,10 @@ def err_operator_overload_needs_class_or_enum : Error<
 def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
 def err_operator_overload_static : Error<
   "overloaded %0 cannot be a static member function">;
+def err_operator_new_param_type : Error<
+  "%0 takes type size_t (%1) as first parameter">;
+def err_operator_new_result_type : Error<
+  "%0 must return type %1">;
 def err_operator_overload_default_arg : Error<
   "parameter of overloaded %0 cannot have a default argument">;
 def err_operator_overload_must_be : Error<
index 25d14a70be2cf002fe7bc26813f55e7cd2ac8936..4be5c62ee04313dd87de9dce8526ff5d4fc3fe60 100644 (file)
@@ -4006,9 +4006,28 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
   //   found in the rest of this subclause do not apply to them unless
   //   explicitly stated in 3.7.3.
   // FIXME: Write a separate routine for checking this. For now, just allow it.
-  if (Op == OO_New || Op == OO_Array_New ||
-      Op == OO_Delete || Op == OO_Array_Delete)
+  if (Op == OO_Delete || Op == OO_Array_Delete)
     return false;
+  
+  if (Op == OO_New || Op == OO_Array_New) {
+    bool ret = false;
+    if (FunctionDecl::param_iterator Param = FnDecl->param_begin()) {
+      QualType SizeTy = Context.getCanonicalType(Context.getSizeType());
+      QualType T = Context.getCanonicalType((*Param)->getType());
+      if (!T->isDependentType() && SizeTy != T) {
+        Diag(FnDecl->getLocation(),
+             diag::err_operator_new_param_type) << FnDecl->getDeclName()
+              << SizeTy;
+        ret = true;
+      }
+    }
+    QualType ResultTy = Context.getCanonicalType(FnDecl->getResultType());
+    if (!ResultTy->isDependentType() && ResultTy != Context.VoidPtrTy)
+      return Diag(FnDecl->getLocation(),
+                  diag::err_operator_new_result_type) << FnDecl->getDeclName()
+                  << Context.VoidPtrTy;
+    return ret;
+  }
 
   // C++ [over.oper]p6:
   //   An operator function shall either be a non-static member
index d4c698d06381bbae1fc095b8d839c914a92682f6..03f528cfbe78ddb5bd4b72e33a3f50711a6c84dd 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: clang-cc -emit-llvm-only -verify %s
 // PR5454
 
-class X {static void * operator new(unsigned size) throw(); X(int); };
+class X {static void * operator new(unsigned long size) throw(); X(int); };
 int a(), b();
 void b(int x)
 {
index 6f3e9effe5381501759319bc9d72ce6ba3f37581..bc385ee60789304c44e00a2adf2d1d59b049c1cd 100644 (file)
@@ -137,3 +137,31 @@ class X5 {
 public:
   void Destroy() const { delete this; }
 };
+
+class Base {
+public:
+  static int operator new(unsigned size) throw(); // expected-error {{'operator new' takes type size_t}} \
+                                                 // expected-error {{operator new' must return type 'void *'}}
+  static int operator new[] (unsigned size) throw(); // expected-error {{'operator new[]' takes type size_t}} \
+                                                    // expected-error {{operator new[]' must return type 'void *'}}
+};
+
+class Tier {};
+class Comp : public Tier {};
+
+class Thai : public Base {
+public:
+  Thai(const Tier *adoptDictionary);
+};
+
+void loadEngineFor() {
+  const Comp *dict;
+  new Thai(dict);
+}
+
+template <class T> struct TBase {
+  void* operator new(T size, int); // expected-error {{'operator new' takes type size_t}}
+};
+
+TBase<int> t1; // expected-note {{in instantiation of template class 'struct TBase<int>' requested here}}
+