diff options
-rw-r--r-- | clang/include/clang/Basic/LangOptions.def | 1 | ||||
-rw-r--r-- | clang/include/clang/Driver/Options.td | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp | 16 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/implicit-allocation-functions.cpp | 16 |
8 files changed, 38 insertions, 17 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index e0a2b22daa2..0320f4dd90b 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -162,6 +162,7 @@ LANGOPT(CUDAIsDevice , 1, 0, "Compiling for CUDA device") LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions") +LANGOPT(DefaultSizedDelete , 1, 0, "Generate weak definitions of sized delete") BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records") BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5f10e8a38f1..d49cf914105 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -394,6 +394,8 @@ def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]> def fno_asm_blocks : Flag<["-"], "fno-asm-blocks">, Group<f_Group>; def fassume_sane_operator_new : Flag<["-"], "fassume-sane-operator-new">, Group<f_Group>; +def fdef_sized_delete: Flag<["-"], "fdef-sized-delete">, Group<f_Group>, + HelpText<"Allow compiler-generated definition of sized deallocation function">, Flags<[CC1Option]>; def fastcp : Flag<["-"], "fastcp">, Group<f_Group>; def fastf : Flag<["-"], "fastf">, Group<f_Group>; def fast : Flag<["-"], "fast">, Group<f_Group>; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 79425d4c21e..4d03bdb8ef4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -891,8 +891,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, } else if (FunctionDecl *UnsizedDealloc = FD->getCorrespondingUnsizedGlobalDeallocationFunction()) { // Global sized deallocation functions get an implicit weak definition if - // they don't have an explicit definition. + // they don't have an explicit definition, if allowed. + assert(getLangOpts().DefaultSizedDelete && + "Can't emit unallowed definition."); EmitSizedDeallocationFunction(*this, UnsizedDealloc); + } else llvm_unreachable("no definition for emitted function"); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bc52028a064..fdcbe2a42e8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1615,13 +1615,13 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, // don't need it anymore). addDeferredDeclToEmit(F, DDI->second); DeferredDecls.erase(DDI); - + // Otherwise, if this is a sized deallocation function, emit a weak - // definition - // for it at the end of the translation unit. + // definition for it at the end of the translation unit. } else if (D && cast<FunctionDecl>(D) ->getCorrespondingUnsizedGlobalDeallocationFunction()) { - addDeferredDeclToEmit(F, GD); + if (getLangOpts().DefaultSizedDelete) + 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 diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 0f74ea176ca..fafd2145fcd 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -4243,6 +4243,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, options::OPT_fno_assume_sane_operator_new)) CmdArgs.push_back("-fno-assume-sane-operator-new"); + + // -def-sized-delete: default implementation of sized delete as a + // weak definition. + if (Args.hasArg(options::OPT_fdef_sized_delete)) + CmdArgs.push_back("-fdef-sized-delete"); // -fconstant-cfstrings is default, and may be subject to argument translation // on Darwin. diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index ee671681b48..b060712f672 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1525,6 +1525,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin); Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.SizedDeallocation |= Args.hasArg(OPT_fsized_deallocation); + Opts.DefaultSizedDelete = Opts.SizedDeallocation && + Args.hasArg(OPT_fdef_sized_delete); Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); Opts.AccessControl = !Args.hasArg(OPT_fno_access_control); Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors); diff --git a/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp b/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp index 7fd3ece3e02..638ea1d20fe 100644 --- a/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp +++ b/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// 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 -fdef-sized-delete -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 --check-prefix=CHECKUND +// RUN: %clang_cc1 -std=c++11 -fsized-deallocation -fdef-sized-delete %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 // CHECK-UNSIZED-NOT: _ZdlPvm @@ -50,8 +52,9 @@ D::D() {} // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4) // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}}) -// CHECK-LABEL: define linkonce void @_ZdlPvm(i8* -// CHECK: call void @_ZdlPv(i8* %0) +// CHECKDEF-LABEL: define linkonce void @_ZdlPvm(i8* +// CHECKDEF: call void @_ZdlPv(i8* %0) +// CHECKUND-LABEL: declare void @_ZdlPvm(i8* // CHECK-LABEL: define weak_odr void @_Z3delI1BEvv() // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4) @@ -71,8 +74,9 @@ D::D() {} // CHECK: add i64 %{{[^ ]*}}, 8 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}}) -// CHECK-LABEL: define linkonce void @_ZdaPvm(i8* -// CHECK: call void @_ZdaPv(i8* %0) +// CHECKDEF-LABEL: define linkonce void @_ZdaPvm(i8* +// CHECKDEF: call void @_ZdaPv(i8* %0) +// CHECKUND-LABEL: declare void @_ZdaPvm(i8* // CHECK-LABEL: define weak_odr void @_Z3delI1DEvv() // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8) diff --git a/clang/test/CodeGenCXX/implicit-allocation-functions.cpp b/clang/test/CodeGenCXX/implicit-allocation-functions.cpp index ed2eb24d56a..9ab0c06ea86 100644 --- a/clang/test/CodeGenCXX/implicit-allocation-functions.cpp +++ b/clang/test/CodeGenCXX/implicit-allocation-functions.cpp @@ -1,7 +1,9 @@ // 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 %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -// RUN: %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 +// RUN: %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 +// RUN: %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 +// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fdef-sized-delete %s 2>&1 | FileCheck %s -check-prefix=CHECKDEF -check-prefix=CHECK14 -check-prefix=CHECK14DEF +// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-unknown -o - -std=c++14 -fdef-sized-delete -fvisibility hidden %s 2>&1 | FileCheck %s -check-prefix=CHECKHID -check-prefix=CHECK14 -check-prefix=CHECK14DEF // PR22419: Implicit sized deallocation functions always have default visibility. // Generalized to all implicit allocation functions. @@ -27,8 +29,9 @@ void foo(A* is) { // CHECK11-DAG: declare void @_ZdlPv(i8*) // CHECK14-DAG: declare noalias i8* @_Znwm(i64) -// CHECK14-DAG: define linkonce void @_ZdlPvm(i8*, i64) -// CHECK14-DAG: declare void @_ZdlPv(i8*) +// CHECK14UND-DAG: declare void @_ZdlPvm(i8*, i64) +// CHECK14DEF-DAG: define linkonce void @_ZdlPvm(i8*, i64) +// CHECK14DEF-DAG: declare void @_ZdlPv(i8*) // CHECK14-DAG: %struct.B = type { i8 } struct B { ~B() { }}; @@ -50,5 +53,6 @@ void f(B *p) { // CHECK11-DAG: declare void @_ZdaPv(i8*) // CHECK14-DAG: declare noalias i8* @_Znam(i64) -// CHECK14-DAG: define linkonce void @_ZdaPvm(i8*, i64) -// CHECK14-DAG: declare void @_ZdaPv(i8*) +// CHECK14UND-DAG: declare void @_ZdaPvm(i8*, i64) +// CHECK14DEF-DAG: define linkonce void @_ZdaPvm(i8*, i64) +// CHECK14DEF-DAG: declare void @_ZdaPv(i8*) |