[cfe-commits] r72677 - in /cfe/trunk: include/clang/AST/Type.h lib/CodeGen/CGCXX.cpp test/CodeGenCXX/new.cpp

Anders Carlsson andersca at mac.com
Sun May 31 14:53:59 PDT 2009


Author: andersca
Date: Sun May 31 16:53:59 2009
New Revision: 72677

URL: http://llvm.org/viewvc/llvm-project?rev=72677&view=rev
Log:
Improve irgen of 'new' further.

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/test/CodeGenCXX/new.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=72677&r1=72676&r2=72677&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sun May 31 16:53:59 2009
@@ -1225,6 +1225,9 @@
     assert(i < NumExceptions && "Invalid exception number!");
     return exception_begin()[i];
   }
+  bool hasEmptyExceptionSpec() const { 
+    return hasExceptionSpec() && getNumExceptions() == 0;
+  }
 
   bool isVariadic() const { return getSubClassData(); }
   unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=72677&r1=72676&r2=72677&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sun May 31 16:53:59 2009
@@ -285,11 +285,23 @@
              CGM.GetAddrOfFunction(GlobalDecl(NewFD)),
              NewArgs, NewFD);
 
-  llvm::Value *NewPtr = Builder.CreateBitCast(RV.getScalarVal(), 
-                                              ConvertType(E->getType()));
-
+  // If an allocation function is declared with an empty exception specification
+  // it returns null to indicate failure to allocate storage. [expr.new]p13.
+  // (We don't need to check for null when there's no new initializer and
+  // we're allocating a POD type).
+  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
+    !(AllocType->isPODType() && !E->hasInitializer());
+
+  if (NullCheckResult) {
+    ErrorUnsupported(E, "new expr that needs to be null checked");
+    return llvm::UndefValue::get(ConvertType(E->getType()));
+  }
+  
+  llvm::Value *NewPtr = 
+    Builder.CreateBitCast(RV.getScalarVal(), ConvertType(E->getType()));
+  
   if (AllocType->isPODType()) {
-    if (E->getNumConstructorArgs() != 0) {
+    if (E->hasInitializer()) {
       assert(E->getNumConstructorArgs() == 1 && 
              "Can only have one argument to initializer of POD type.");
 
@@ -302,12 +314,16 @@
       else
         EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
     }
+  } else {
+    // Call the constructor.    
+    CXXConstructorDecl *Ctor = E->getConstructor();
     
-    return NewPtr;
+    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr, 
+                           E->constructor_arg_begin(), 
+                           E->constructor_arg_end());
   }
-  
-  ErrorUnsupported(E, "new expression with non-POD type");
-  return llvm::UndefValue::get(ConvertType(E->getType()));
+
+  return NewPtr;
 }
 
 static bool canGenerateCXXstructor(const CXXRecordDecl *RD, 

Modified: cfe/trunk/test/CodeGenCXX/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/new.cpp?rev=72677&r1=72676&r2=72677&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/new.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/new.cpp Sun May 31 16:53:59 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc %s -emit-llvm -o %t
+// RUN: clang-cc %s -emit-llvm -o %t &&
 
 void t1() {
   int* a = new int;
@@ -15,6 +15,7 @@
   int a;
 };
 
+// POD types.
 void t3() {
   int *a = new int(10);
   _Complex int* b = new _Complex int(10i);
@@ -23,3 +24,24 @@
   s.a = 10;
   S *sp = new S(s);
 }
+
+// Non-POD
+struct T {
+  T();
+  int a;
+};
+
+void t4() {
+  // RUN: grep "call void @_ZN1TC1Ev" %t | count 1 &&
+  T *t = new T;
+}
+
+struct T2 {
+  int a;
+  T2(int, int);
+};
+
+void t5() { 
+  // RUN: grep "call void @_ZN2T2C1Eii" %t | count 1 
+  T2 *t2 = new T2(10, 10);
+}





More information about the cfe-commits mailing list