DeferredDecls.erase(DDI);
// Otherwise, if this is a sized deallocation function, emit a weak
- // definition for it at the end of the translation unit.
- } else if (D && cast<FunctionDecl>(D)
- ->getCorrespondingUnsizedGlobalDeallocationFunction()) {
- if (getLangOpts().DefaultSizedDelete)
- addDeferredDeclToEmit(F, GD);
+ // definition for it at the end of the translation unit (if allowed),
+ // unless the sized deallocation function is aliased.
+ } else if (D &&
+ cast<FunctionDecl>(D)
+ ->getCorrespondingUnsizedGlobalDeallocationFunction() &&
+ !getLangOpts().DefaultSizedDelete &&
+ !D->hasAttr<AliasAttr>()) {
+ addDeferredDeclToEmit(F, GD);
// Otherwise, there are cases we have to worry about where we're
// using a declaration for which we must emit a definition but where
--- /dev/null
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y %s -o -
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++1y %s -fdef-sized-delete -o -
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation %s -o -
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 -fsized-deallocation -fdef-sized-delete %s -o -
+// RUN: %clang -cc1 -emit-llvm -triple x86_64-unknown-unknown -std=c++11 %s -o -
+
+// CHECK-UNSIZED-NOT: _ZdlPvm
+// CHECK-UNSIZED-NOT: _ZdaPvm
+
+void operator delete(void*, unsigned long) throw() __attribute__((alias("foo")));
+extern "C" void foo(void*, unsigned long) {}
+
+// CHECK-DAG: @_ZdlPvm = alias void (i8*, i64)* @my_delete