r230580 - Improvement on sized deallocation from r230160:

Larisse Voufo lvoufo at google.com
Wed Feb 25 15:48:43 PST 2015


Author: lvoufo
Date: Wed Feb 25 17:48:43 2015
New Revision: 230580

URL: http://llvm.org/viewvc/llvm-project?rev=230580&view=rev
Log:
Improvement on sized deallocation from r230160:
Do not declare sized deallocation functions dependently on whether it is found in global scope. Instead, enforce the branching in emitted code by (1) declaring the functions extern_weak and (2) emitting sized delete expressions as a branching between both forms delete.

Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
    cfe/trunk/test/CodeGenCXX/implicit-allocation-functions.cpp
    cfe/trunk/test/CodeGenCXX/pr21754.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=230580&r1=230579&r2=230580&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Feb 25 17:48:43 2015
@@ -1422,6 +1422,71 @@ CodeGenFunction::pushCallObjectDeleteCle
                                         OperatorDelete, ElementType);
 }
 
+static void EmitDelete(CodeGenFunction &CGF,
+                              const CXXDeleteExpr *DE,
+                              llvm::Value *Ptr,
+                              QualType ElementType);
+
+static void EmitSizedDelete(CodeGenFunction &CGF,
+                            const CXXDeleteExpr *DE,
+                            llvm::Value *Ptr,
+                            QualType ElementType,
+                            FunctionDecl* UnsizedDealloc) {
+
+  if (CGF.getLangOpts().DefineSizedDeallocation) {
+    // The delete operator in use is fixed. So simply emit the delete expr.
+    EmitDelete(CGF, DE, Ptr, ElementType);
+    return;
+  }
+
+  assert(UnsizedDealloc && "We must be emiting a 'sized' delete expr");
+
+  // Branch off over the value of operator delete:
+  // Use the sized form if available, and default on the unsized form otherwise.
+  llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("if.then");
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("if.end");
+  llvm::BasicBlock *ElseBlock = CGF.createBasicBlock("if.else");
+
+  // Emit the condition.
+  const FunctionDecl *OpDelFD = DE->getOperatorDelete();
+  llvm::Value *OpDelAddr = CGF.CGM.GetAddrOfFunction(OpDelFD);
+  //llvm::Function *OpDel = dyn_cast<llvm::Function>(OpDelAddr);
+  llvm::Value *SDE = CGF.Builder.CreateIsNotNull(OpDelAddr, "sized.del.exists");
+  CGF.Builder.CreateCondBr(SDE, ThenBlock, ElseBlock);
+
+  // Emit the 'then' code.
+  CGF.EmitBlock(ThenBlock);
+  EmitDelete(CGF, DE, Ptr, ElementType);
+  CGF.EmitBranch(ContBlock);
+
+  // Compute the 'unsized' delete expr.
+  CXXDeleteExpr * E = const_cast<CXXDeleteExpr*>(DE);
+  CXXDeleteExpr *UnsizedDE =
+  new (CGF.getContext()) CXXDeleteExpr(CGF.getContext().VoidTy,
+                                       E->isGlobalDelete(),
+                                       E->isArrayForm(),
+                                       E->isArrayFormAsWritten(),
+                                       E->doesUsualArrayDeleteWantSize(),
+                                       UnsizedDealloc,
+                                       E->getArgument(),
+                                       E->getLocStart());
+  // Emit the 'else' code.
+  {
+    // There is no need to emit line number for an unconditional branch.
+    auto NL = ApplyDebugLocation::CreateEmpty(CGF);
+    CGF.EmitBlock(ElseBlock);
+  }
+  EmitDelete(CGF, UnsizedDE, Ptr, ElementType);
+  {
+    // There is no need to emit line number for an unconditional branch.
+    auto NL = ApplyDebugLocation::CreateEmpty(CGF);
+    CGF.EmitBranch(ContBlock);
+  }
+
+  // Emit the continuation block for code after the if.
+  CGF.EmitBlock(ContBlock, true);
+}
+
 /// Emit the code for deleting a single object.
 static void EmitObjectDelete(CodeGenFunction &CGF,
                              const CXXDeleteExpr *DE,
@@ -1581,6 +1646,17 @@ static void EmitArrayDelete(CodeGenFunct
   CGF.PopCleanupBlock();
 }
 
+static void EmitDelete(CodeGenFunction &CGF,
+                       const CXXDeleteExpr *DE,
+                       llvm::Value *Ptr,
+                       QualType ElementType) {
+  if (DE->isArrayForm()) {
+    EmitArrayDelete(CGF, DE, Ptr, ElementType);
+  } else {
+    EmitObjectDelete(CGF, DE, Ptr, ElementType);
+  }
+}
+
 void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
   const Expr *Arg = E->getArgument();
   llvm::Value *Ptr = EmitScalarExpr(Arg);
@@ -1620,11 +1696,12 @@ void CodeGenFunction::EmitCXXDeleteExpr(
   assert(ConvertTypeForMem(DeleteTy) ==
          cast<llvm::PointerType>(Ptr->getType())->getElementType());
 
-  if (E->isArrayForm()) {
-    EmitArrayDelete(*this, E, Ptr, DeleteTy);
-  } else {
-    EmitObjectDelete(*this, E, Ptr, DeleteTy);
-  }
+  const FunctionDecl *Dealloc = E->getOperatorDelete();
+  if (FunctionDecl* UnsizedDealloc =
+      Dealloc->getCorrespondingUnsizedGlobalDeallocationFunction())
+    EmitSizedDelete(*this, E, Ptr, DeleteTy, UnsizedDealloc);
+  else
+    EmitDelete(*this, E, Ptr, DeleteTy);
 
   EmitBlock(DeleteEnd);
 }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=230580&r1=230579&r2=230580&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Feb 25 17:48:43 2015
@@ -2090,15 +2090,6 @@ void Sema::DeclareGlobalAllocationFuncti
     }
   }
   
-  // If the function is sized operator delete and has not already been
-  // declared, and weak definitions have been disabled, do not declare
-  // it implicitly. Instead, let deallocation function lookup pick up
-  // unsized delete.
-  // FIXME: We should remove this guard once backward compatibility is
-  // no longer an issue
-  if (NumParams == 2 && !getLangOpts().DefineSizedDeallocation)
-    return;
-
   FunctionProtoType::ExtProtoInfo EPI;
 
   QualType BadAllocType;
@@ -2131,6 +2122,16 @@ void Sema::DeclareGlobalAllocationFuncti
   Alloc->addAttr(VisibilityAttr::CreateImplicit(Context,
                                                 VisibilityAttr::Default));
 
+  if (NumParams == 2 && !getLangOpts().DefineSizedDeallocation) {
+    assert(getLangOpts().SizedDeallocation &&
+           "Only sized deallocation can have two parameters");
+
+    // This declaration should be emited as extern_weak.
+    LinkageInfo LV = Alloc->getLinkageAndVisibility();
+    assert(LV.getLinkage() == clang::ExternalLinkage);
+    Alloc->addAttr(WeakAttr::CreateImplicit(Context));
+  }
+
   if (AddRestrictAttr)
     Alloc->addAttr(
         RestrictAttr::CreateImplicit(Context, RestrictAttr::GNU_malloc));

Modified: cfe/trunk/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1y-sized-deallocation.cpp?rev=230580&r1=230579&r2=230580&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx1y-sized-deallocation.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx1y-sized-deallocation.cpp Wed Feb 25 17:48:43 2015
@@ -1,8 +1,6 @@
-// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
-// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - -DINLIB | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
+// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
 // RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -fdefine-sized-deallocation -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEF
-// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
-// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - -DINLIB | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
+// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKUND
 // RUN: %clang_cc1 -std=c++11 -fsized-deallocation -fdefine-sized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEF
 // RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
 // RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -fno-sized-deallocation -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
@@ -12,11 +10,6 @@
 
 typedef decltype(sizeof(0)) size_t;
 
-#ifdef INLIB
-void operator delete(void *, size_t) noexcept;
-void operator delete[](void *, size_t) noexcept;
-#endif
-
 typedef int A;
 struct B { int n; };
 struct C { ~C() {} };
@@ -54,63 +47,92 @@ template void del<F>();
 D::D() {}
 
 // CHECK-LABEL: define weak_odr void @_Z3delIiEvv()
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 //
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECKDEF-LABEL: define linkonce void @_ZdlPvm(i8*, i64) #{{[0-9]+}} comdat
 // CHECKDEF: call void @_ZdlPv(i8* %0)
-// CHECKUND-LABEL: declare void @_ZdlPvm(i8*
+// CHECKUND-LABEL: declare extern_weak void @_ZdlPvm(i8*
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1BEvv()
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 //
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1CEvv()
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
 //
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECKDEF-LABEL: define linkonce void @_ZdaPvm(i8*, i64) #{{[0-9]+}} comdat
 // CHECKDEF: call void @_ZdaPv(i8* %0)
-// CHECKUND-LABEL: declare void @_ZdaPvm(i8*
+// CHECKUND-LABEL: declare extern_weak void @_ZdaPvm(i8*
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1DEvv()
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
 // CHECK: mul i64 8, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
 //
-// CHECK-NOT: Zdl
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
+// CHECKDEF-NOT: Zdl
 // CHECK: call void %{{.*}}
 // CHECK-NOT: Zdl
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
 // CHECK: mul i64 8, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1EEvv()
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 //
 // CHECK: call void @_ZN1EdlEPv(i8* %{{[^ ]*}})
 // CHECK: call void @_ZN1EdaEPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1FEvv()
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECKUND: call void @_ZdlPv(i8* %{{[^ ]*}})
+// CHECKUND: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+// CHECKUND: call void @_ZdaPv(i8* %{{[^ ]*}})
 //
 // CHECK: call void @_ZN1FdlEPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: mul i64 1, %{{[^ ]*}}

Modified: cfe/trunk/test/CodeGenCXX/implicit-allocation-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/implicit-allocation-functions.cpp?rev=230580&r1=230579&r2=230580&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/implicit-allocation-functions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/implicit-allocation-functions.cpp Wed Feb 25 17:48:43 2015
@@ -1,21 +1,15 @@
 // RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++11 %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK11
 // RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++11 -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK11
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fno-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK11
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14UND
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14UND
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fdefine-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -DINLIB -fdefine-sized-deallocation -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-macosx -o - -std=c++14 -DINLIB -fdefine-sized-deallocation %s | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFNOCOMDAT
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fno-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK11
+// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14UND
+// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14UND
+// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fdefine-sized-deallocation %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
+// RU N: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fdefine-sized-deallocation -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14DEFCOMDAT
+// RU N: %clang_cc1 -emit-llvm -triple x86_64-apple-macosx -o - -std=c++14 -fdefine-sized-deallocation %s | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEFNOCOMDAT
 
 // PR22419: Implicit sized deallocation functions always have default visibility.
 //   Generalized to all implicit allocation functions.
 
-#ifdef INLIB
-typedef decltype(sizeof(0)) size_t;
-void operator delete(void *, size_t) noexcept;
-void operator delete[](void *, size_t) noexcept;
-#endif
-
 // CHECK14-DAG: %struct.A = type { i8 }
 struct A { };
 
@@ -28,7 +22,9 @@ void foo(A* is) {
   is = new A();
 
   // CHECK11-DAG: call void @_ZdlPv(i8* %{{.+}})
+  // CHECK14UND-DAG: br i1 icmp ne (void (i8*, i64)* @_ZdlPvm, void (i8*, i64)* null),
   // CHECK14-DAG: call void @_ZdlPvm(i8* %{{.+}}, i64 1)
+  // CHECK14UND-DAG: call void @_ZdlPv(i8* %{{.+}})
   delete is;
 }
 
@@ -36,7 +32,7 @@ void foo(A* is) {
 // CHECK11-DAG: declare void @_ZdlPv(i8*)
 
 // CHECK14-DAG: declare noalias i8* @_Znwm(i64)
-// CHECK14UND-DAG: declare void @_ZdlPvm(i8*, i64)
+// CHECK14UND-DAG: declare extern_weak void @_ZdlPvm(i8*, i64)
 // CHECK14DEFCOMDAT-DAG: define linkonce void @_ZdlPvm(i8*, i64) #{{[0-9]+}} comdat {
 // CHECK14DEFCOMDAT-DAG: declare void @_ZdlPv(i8*)
 // CHECK14DEFNOCOMDAT-DAG: define linkonce void @_ZdlPvm(i8*, i64) #{{[0-9]+}} {
@@ -54,7 +50,9 @@ void f(B *p) {
   p = new B[5];
 
   // CHECK11-DAG: call void @_ZdaPv(i8* %{{.+}})
+  // CHECK14UND-DAG: br i1 icmp ne (void (i8*, i64)* @_ZdaPvm, void (i8*, i64)* null),
   // CHECK14-DAG: call void @_ZdaPvm(i8* %{{.+}}, i64 %{{.+}})
+  // CHECK14UND-DAG: call void @_ZdaPv(i8* %{{.+}})
   delete[] p;
 }
 
@@ -62,7 +60,7 @@ void f(B *p) {
 // CHECK11-DAG: declare void @_ZdaPv(i8*)
 
 // CHECK14-DAG: declare noalias i8* @_Znam(i64)
-// CHECK14UND-DAG: declare void @_ZdaPvm(i8*, i64)
+// CHECK14UND-DAG: declare extern_weak void @_ZdaPvm(i8*, i64)
 // CHECK14DEF-DAG: define linkonce void @_ZdaPvm(i8*, i64) #{{[0-9]+}} comdat {
 // CHECK14DEF-DAG: declare void @_ZdaPv(i8*)
 // CHECK14DEFNOCOMDAT-DAG: define linkonce void @_ZdaPvm(i8*, i64) #{{[0-9]+}} {

Modified: cfe/trunk/test/CodeGenCXX/pr21754.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pr21754.cpp?rev=230580&r1=230579&r2=230580&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pr21754.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/pr21754.cpp Wed Feb 25 17:48:43 2015
@@ -1,11 +1,13 @@
-// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -o - %s 2>&1 | FileCheck %s
-// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s
-// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fno-sized-deallocation -o - %s 2>&1 | FileCheck %s
-// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -o - %s 2>&1 | FileCheck %s
-// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s
-// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -o - %s 2>&1 | FileCheck %s
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -o - %s 2>&1 | FileCheck %s  --check-prefix=CHECKUND
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKDEF
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y -fno-sized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKNO
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKUND
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -fdefine-sized-deallocation -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKDEF
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -o - %s 2>&1 | FileCheck %s --check-prefix=CHECKNO
 
 void operator delete(void*, unsigned long) throw() __attribute__((alias("foo")));
 extern "C" void foo(void*, unsigned long) {}
 
-// CHECK-DAG: @_ZdlPvm = alias void (i8*, i64)* @foo
+// CHECKUND-DAG: @_ZdlPvm = weak alias void (i8*, i64)* @foo
+// CHECKDEF-DAG: @_ZdlPvm = alias void (i8*, i64)* @foo
+// CHECKNO-DAG: @_ZdlPvm = alias void (i8*, i64)* @foo





More information about the cfe-commits mailing list