https://github.com/bd1976bris updated https://github.com/llvm/llvm-project/pull/75364
>From 97efed8c73aed4fdca5510013c844e84953ec256 Mon Sep 17 00:00:00 2001 From: Ben Dunbobbin <ben.dunbob...@sony.com> Date: Tue, 12 Dec 2023 08:07:17 +0000 Subject: [PATCH 1/2] [Sema] Provide `-fno-/-fvisibility-global-new-delete` option By default the implicitly declared replaceable global new and delete operators are given a `default` visibility attribute. Previous work, see: https://reviews.llvm.org/D53787, added `-fvisibility-global-new-delete-hidden` to change this to a `hidden` visibility attribute. This change adds: `-fno/-fvisibility-global-new-delete` which controls whether or not to add a visibility attribute to the implicit declarations for these functions. Without the attribute the replaceable global new and delete operators behave normally (like other functions) with respect to visibility attributes, pragmas and options. The command line help for these options is rendered as: -fvisibility-global-new-delete Add a visibility attribute to the implicit global C++ operator new and delete declarations -fno-visibility-global-new-delete Do not add a visibility attribute to the implicit global C++ operator new and delete declarations The motivation is to allow users to specify `-fno-visibility-global-new-delete` when they intend to replace these functions either for a single linkage unit or set of linkage units. `-fno-visibility-global-new-delete` can be applied globally to the compilations in a build where `-fvisibility-global-new-delete-hidden` cannot; as it conflicts with a common pattern where these functions are dynamically imported. `-fno-visibility-global-new-delete` makes sense as the default for PS5. Users that want the normal toolchain behaviour will be able to supply `-fvisibility-global-new-delete`. --- clang/include/clang/Basic/LangOptions.def | 3 +- clang/include/clang/Driver/Options.td | 6 +++ clang/lib/Driver/ToolChains/Clang.cpp | 12 +++++ clang/lib/Driver/ToolChains/PS4CPU.cpp | 6 +++ clang/lib/Sema/SemaExprCXX.cpp | 9 ++-- .../visibility-global-new-delete.cpp | 13 +++++ .../Driver/visibility-global-new-delete.cl | 47 +++++++++++++++++++ 7 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenCXX/visibility-global-new-delete.cpp create mode 100644 clang/test/Driver/visibility-global-new-delete.cl diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index c3d5399905a3fd..1471fc11e11663 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -306,7 +306,8 @@ BENIGN_LANGOPT(IgnoreXCOFFVisibility, 1, 0, "All the visibility attributes that BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0, "hidden visibility for static local variables in inline C++ " "methods when -fvisibility-inlines hidden is enabled") -LANGOPT(GlobalAllocationFunctionVisibilityHidden , 1, 0, "hidden visibility for global operator new and delete declaration") +LANGOPT(GlobalAllocationFunctionVisibility, 1, 1, "add a visibility attribute to the implicit global operator new and delete declarations") +LANGOPT(GlobalAllocationFunctionVisibilityHidden, 1, 0, "hidden visibility for global operator new and delete declarations") LANGOPT(NewInfallible , 1, 0, "Treats throwing global C++ operator new as always returning valid memory (annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.") BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype") BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index db2190318c931a..a9f43b18df6fbf 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3863,6 +3863,12 @@ defm visibility_inlines_hidden_static_local_var : BoolFOption<"visibility-inline def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>, HelpText<"Give global types 'default' visibility and global functions and " "variables 'hidden' visibility by default">; +defm visibility_global_new_delete : BoolFOption<"visibility-global-new-delete", + LangOpts<"GlobalAllocationFunctionVisibility">, DefaultTrue, + PosFlag<SetTrue, [], [ClangOption], "Add">, + NegFlag<SetFalse, [], [ClangOption], "Do not add">, + BothFlags<[], [ClangOption, CC1Option], + " a visibility attribute to the implicit global C++ operator new and delete declarations">>; def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group<f_Group>, HelpText<"Give global C++ operator new and delete declarations hidden visibility">, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f02f7c841b91f0..979e2a0e83be37 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6204,7 +6204,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var, options::OPT_fno_visibility_inlines_hidden_static_local_var); + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete, + options::OPT_fno_visibility_global_new_delete); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); + // Error for incompatible global new and delete directives. + const Arg *N = Args.getLastArg(options::OPT_fvisibility_global_new_delete, + options::OPT_fno_visibility_global_new_delete); + if (N && + N->getOption().matches(options::OPT_fno_visibility_global_new_delete)) { + if (Arg *H = + Args.getLastArg(options::OPT_fvisibility_global_new_delete_hidden)) + D.Diag(diag::err_drv_incompatible_options) + << N->getSpelling() << H->getSpelling(); + } Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); if (Args.hasFlag(options::OPT_fnew_infallible, diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp index 5fd82d1da19926..a535d5fb2a7200 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -359,6 +359,12 @@ void toolchains::PS4PS5Base::addClangTargetOptions( CC1Args.push_back("-fno-use-init-array"); + // Default to -fno-visibility-global-new-delete for PS5. + if (getTriple().isPS5() && + !DriverArgs.hasArg(options::OPT_fvisibility_global_new_delete, + options::OPT_fno_visibility_global_new_delete, + options::OPT_fvisibility_global_new_delete_hidden)) + CC1Args.push_back("-fno-visibility-global-new-delete"); const Arg *A = DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, options::OPT_fno_visibility_from_dllstorageclass); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 081b568762ae22..29480a1e0c0346 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3222,10 +3222,11 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, Alloc->setLocalOwningModule(TheGlobalModuleFragment); } - Alloc->addAttr(VisibilityAttr::CreateImplicit( - Context, LangOpts.GlobalAllocationFunctionVisibilityHidden - ? VisibilityAttr::Hidden - : VisibilityAttr::Default)); + if (LangOpts.GlobalAllocationFunctionVisibility) + Alloc->addAttr(VisibilityAttr::CreateImplicit( + Context, LangOpts.GlobalAllocationFunctionVisibilityHidden + ? VisibilityAttr::Hidden + : VisibilityAttr::Default)); llvm::SmallVector<ParmVarDecl *, 3> ParamDecls; for (QualType T : Params) { diff --git a/clang/test/CodeGenCXX/visibility-global-new-delete.cpp b/clang/test/CodeGenCXX/visibility-global-new-delete.cpp new file mode 100644 index 00000000000000..b29a5f01e9a647 --- /dev/null +++ b/clang/test/CodeGenCXX/visibility-global-new-delete.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -emit-llvm -o - | FileCheck %s -DLINKAGE=dso_local +// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -fvisibility-global-new-delete -emit-llvm -o - | FileCheck %s -DLINKAGE=dso_local +// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -fno-visibility-global-new-delete -emit-llvm -o - | FileCheck %s -DLINKAGE=hidden +// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -fvisibility-global-new-delete-hidden -emit-llvm -o - | FileCheck %s -DLINKAGE=hidden + +namespace std { + typedef __typeof__(sizeof(0)) size_t; + struct nothrow_t {}; +} + +// Definition which inherits visibility from the implicit compiler generated declaration. +void operator delete(void*) throw() {} +// CHECK: define [[LINKAGE]] void @_ZdlPv diff --git a/clang/test/Driver/visibility-global-new-delete.cl b/clang/test/Driver/visibility-global-new-delete.cl new file mode 100644 index 00000000000000..08e3a812887452 --- /dev/null +++ b/clang/test/Driver/visibility-global-new-delete.cl @@ -0,0 +1,47 @@ +/// Check driver handling for "-fvisibility-global-new-delete-hidden" and "-fvisibility-global-new-delete". + +/// These options are not added by default. +// RUN: %clang -### -target x86_64-unknown-unknown -x cl -c -emit-llvm %s 2>&1 | \ +// RUN: FileCheck -check-prefix=DEFAULTS %s +// DEFAULTS-NOT: "-fvisibility-global-new-delete" +// DEFAULTS-NOT: "-fno-visibility-global-new-delete" +// DEFAULTS-NOT: "-fvisibility-global-new-delete-hidden" + +// DEFINE: %{implicit-check-nots} = --implicit-check-not=-fvisibility-global-new-delete --implicit-check-not=-fno-visibility-global-new-delete + +/// "-fno-visibility-global-new-delete" added by default for PS5. +// RUN: %clang -### -target x86_64-sie-ps5 -x cl -c -emit-llvm %s 2>&1 | \ +// RUN: FileCheck -check-prefix=PS5 %s +// PS5: "-fno-visibility-global-new-delete" + +/// -fvisibility-global-new-delete-hidden added explicitly. +// RUN: %clang -### -target x86_64-unknown-unknown -x cl -c -emit-llvm \ +// RUN: -fvisibility-global-new-delete-hidden %s 2>&1 | FileCheck -check-prefixes=HIDDEN %s %{implicit-check-nots} +// RUN: %clang -### -target x86_64-sie-ps5 -x cl -c -emit-llvm \ +// RUN: -fvisibility-global-new-delete-hidden %s 2>&1 | FileCheck -check-prefixes=HIDDEN %s %{implicit-check-nots} +// HIDDEN-DAG: "-fvisibility-global-new-delete-hidden" + +/// -fvisibility-global-new-delete added explicitly. +// RUN: %clang -### -target x86_64-unknown-unknown -x cl -c -emit-llvm \ +// RUN: -fvisibility-global-new-delete %s 2>&1 | FileCheck -check-prefixes=VGND %s %{implicit-check-nots} +// RUN: %clang -### -target x86_64-sie-ps5 -x cl -c -emit-llvm \ +// RUN: -fvisibility-global-new-delete %s 2>&1 | FileCheck -check-prefixes=VGND %s %{implicit-check-nots} +// VGND-DAG: "-fvisibility-global-new-delete" + +/// -fno-visibility-global-new-delete added explicitly. +// RUN: %clang -### -target x86_64-unknown-unknown -x cl -c -emit-llvm \ +// RUN: -fno-visibility-global-new-delete %s 2>&1 | FileCheck -check-prefixes=NO_VGND %s %{implicit-check-nots} +// RUN: %clang -### -target x86_64-sie-ps5 -x cl -c -emit-llvm \ +// RUN: -fno-visibility-global-new-delete %s 2>&1 | FileCheck -check-prefixes=NO_VGND %s %{implicit-check-nots} +// NO_VGND-DAG: "-fno-visibility-global-new-delete" + +/// No error if both -fvisibility-global-new-delete and -fvisibility-global-new-delete-hidden specified. +// RUN: %clang -### -target x86_64-unknown-unknown -x cl -c -emit-llvm \ +// RUN: -fvisibility-global-new-delete-hidden -fvisibility-global-new-delete %s 2>&1 | \ +// RUN: FileCheck -check-prefixes=VGND,HIDDEN %s %{implicit-check-nots} + +/// Error if both -fno-visibility-global-new-delete and -fvisibility-global-new-delete-hidden specified. +// RUN: not %clang -### -target x86_64-unknown-unknown -x cl -c -emit-llvm \ +// RUN: -fvisibility-global-new-delete-hidden -fvisibility-global-new-delete -fno-visibility-global-new-delete %s 2>&1 | \ +// RUN: FileCheck -check-prefixes=INCOMPAT %s +// INCOMPAT: clang: error: the combination of '-fno-visibility-global-new-delete' and '-fvisibility-global-new-delete-hidden' is incompatible >From b48efc45f9b3306a3f740eb58099c7d436b73e43 Mon Sep 17 00:00:00 2001 From: Ben Dunbobbin <ben.dunbob...@sony.com> Date: Thu, 14 Dec 2023 08:30:22 +0000 Subject: [PATCH 2/2] appease CI clang-format check. Previously, I had matched the coding style of the sourrounding code. --- clang/lib/Driver/ToolChains/Clang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 979e2a0e83be37..ae92cfc2d8ee2b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6205,7 +6205,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var, options::OPT_fno_visibility_inlines_hidden_static_local_var); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete, - options::OPT_fno_visibility_global_new_delete); + options::OPT_fno_visibility_global_new_delete); Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden); // Error for incompatible global new and delete directives. const Arg *N = Args.getLastArg(options::OPT_fvisibility_global_new_delete, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits