Skip to content

Commit 27ce26b

Browse files
authored
[Sema] Add -fvisibility-global-new-delete= option (llvm#75364)
[Sema] Add `-fvisibility-global-new-delete=` option (llvm#75364) 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 `-fvisibility-global-new-delete=` which controls whether (or not) to add an implicit visibility attribute to the implicit declarations for these functions, and what visibility that attribute will specify. The option takes 4 values: `force-hidden`, `force-protected`, `force-default` and `source`. Option values `force-hidden`, `force-protected` and `force-default` assign hidden, protected, and default visibilities respectively; the use of the term force in the value names is designed to imply to a user that the semantics of this option differ significantly from `-fvisibility=`. An option value of `source` implies that no implicit attribute is added; without the attribute the replaceable global new and delete operators behave normally (like other functions) with respect to visibility attributes, pragmas and options. The motivation for the `source` value is to facilitate users who intend to replace these functions either for a single linkage unit or a limited set of linkage units. `-fvisibility-global-new-delete=source` can be applied globally to the compilations in a build where the existing `-fvisibility-global-new-delete-hidden` cannot, as it conflicts with a common pattern where these functions are dynamically imported. The existing `-fvisibility-global-new-delete-hidden` is now a deprecated spelling of `-fvisibility-global-new-delete=force-hidden` A release note has been added for these changes. `-fvisibility-global-new-delete=source` will be set by default for PS5. PS5 users that want the normal toolchain behaviour will be able to supply `-fvisibility-global-new-delete=force-default`.
1 parent df4ba00 commit 27ce26b

File tree

9 files changed

+157
-9
lines changed

9 files changed

+157
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ New Compiler Flags
320320
handlers will be smaller. A throw expression of a type with a
321321
potentially-throwing destructor will lead to an error.
322322

323-
* ``-fopenacc`` was added as a part of the effort to support OpenACC in clang.
323+
* ``-fopenacc`` was added as a part of the effort to support OpenACC in Clang.
324324

325325
* ``-fcx-limited-range`` enables the naive mathematical formulas for complex
326326
division and multiplication with no NaN checking of results. The default is
@@ -331,6 +331,16 @@ New Compiler Flags
331331
division. See SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8
332332
(1962). The default is ``-fno-cx-fortran-rules``.
333333

334+
* ``-fvisibility-global-new-delete=<value>`` gives more freedom to users to
335+
control how and if Clang forces a visibility for the replaceable new and
336+
delete declarations. The option takes 4 values: ``force-hidden``,
337+
``force-protected``, ``force-default`` and ``source``; ``force-default`` is
338+
the default. Option values with prefix ``force-`` assign such declarations
339+
an implicit visibility attribute with the corresponding visibility. An option
340+
value of ``source`` implies that no implicit attribute is added. Without the
341+
attribute the replaceable global new and delete operators behave normally
342+
(like other functions) with respect to visibility attributes, pragmas and
343+
options (e.g ``--fvisibility=``).
334344

335345
Deprecated Compiler Flags
336346
-------------------------
@@ -347,6 +357,9 @@ Modified Compiler Flags
347357
``rtdcall``. This new default CC only works for M68k and will use the new
348358
``m68k_rtdcc`` CC on every functions that are not variadic. The ``-mrtd``
349359
driver/frontend flag has the same effect when targeting M68k.
360+
* ``-fvisibility-global-new-delete-hidden`` is now a deprecated spelling of
361+
``-fvisibility-global-new-delete=force-hidden`` (``-fvisibility-global-new-delete=``
362+
is new in this release).
350363

351364
Removed Compiler Flags
352365
-------------------------

clang/include/clang/Basic/LangOptions.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ BENIGN_LANGOPT(IgnoreXCOFFVisibility, 1, 0, "All the visibility attributes that
308308
BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0,
309309
"hidden visibility for static local variables in inline C++ "
310310
"methods when -fvisibility-inlines hidden is enabled")
311-
LANGOPT(GlobalAllocationFunctionVisibilityHidden , 1, 0, "hidden visibility for global operator new and delete declaration")
311+
ENUM_LANGOPT(GlobalAllocationFunctionVisibility, VisibilityForcedKinds, 3, VisibilityForcedKinds::ForceDefault,
312+
"How to apply visibility to global operator new and delete declarations")
312313
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.")
313314
BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
314315
BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")

clang/include/clang/Basic/LangOptions.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,17 @@ class LangOptions : public LangOptionsBase {
381381
All,
382382
};
383383

384+
enum class VisibilityForcedKinds {
385+
/// Force hidden visibility
386+
ForceHidden,
387+
/// Force protected visibility
388+
ForceProtected,
389+
/// Force default visibility
390+
ForceDefault,
391+
/// Don't alter the visibility
392+
Source,
393+
};
394+
384395
enum class VisibilityFromDLLStorageClassKinds {
385396
/// Keep the IR-gen assigned visibility.
386397
Keep,
@@ -673,6 +684,26 @@ class LangOptions : public LangOptionsBase {
673684
DefaultVisiblityExportMapping::All;
674685
}
675686

687+
bool hasGlobalAllocationFunctionVisibility() const {
688+
return getGlobalAllocationFunctionVisibility() !=
689+
VisibilityForcedKinds::Source;
690+
}
691+
692+
bool hasDefaultGlobalAllocationFunctionVisibility() const {
693+
return getGlobalAllocationFunctionVisibility() ==
694+
VisibilityForcedKinds::ForceDefault;
695+
}
696+
697+
bool hasProtectedGlobalAllocationFunctionVisibility() const {
698+
return getGlobalAllocationFunctionVisibility() ==
699+
VisibilityForcedKinds::ForceProtected;
700+
}
701+
702+
bool hasHiddenGlobalAllocationFunctionVisibility() const {
703+
return getGlobalAllocationFunctionVisibility() ==
704+
VisibilityForcedKinds::ForceHidden;
705+
}
706+
676707
/// Remap path prefix according to -fmacro-prefix-path option.
677708
void remapPathPrefix(SmallVectorImpl<char> &Path) const;
678709

clang/include/clang/Driver/Options.td

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3910,9 +3910,16 @@ def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>
39103910
HelpText<"Give global types 'default' visibility and global functions and "
39113911
"variables 'hidden' visibility by default">;
39123912
def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group<f_Group>,
3913-
HelpText<"Give global C++ operator new and delete declarations hidden visibility">,
3913+
HelpText<"Give global C++ operator new and delete declarations hidden visibility">;
3914+
class MarshallingInfoVisibilityGlobalNewDelete<KeyPathAndMacro kpm, code default>
3915+
: MarshallingInfoEnum<kpm, default>,
3916+
Values<"force-default,force-protected,force-hidden,source">,
3917+
NormalizedValuesScope<"LangOptions::VisibilityForcedKinds">,
3918+
NormalizedValues<["ForceDefault", "ForceProtected", "ForceHidden", "Source"]> {}
3919+
def fvisibility_global_new_delete_EQ : Joined<["-"], "fvisibility-global-new-delete=">, Group<f_Group>,
39143920
Visibility<[ClangOption, CC1Option]>,
3915-
MarshallingInfoFlag<LangOpts<"GlobalAllocationFunctionVisibilityHidden">>;
3921+
HelpText<"The visibility for global C++ operator new and delete declarations. If 'source' is specified the visibility is not adjusted">,
3922+
MarshallingInfoVisibilityGlobalNewDelete<LangOpts<"GlobalAllocationFunctionVisibility">, "ForceDefault">;
39163923
def mdefault_visibility_export_mapping_EQ : Joined<["-"], "mdefault-visibility-export-mapping=">,
39173924
Values<"none,explicit,all">,
39183925
NormalizedValuesScope<"LangOptions::DefaultVisiblityExportMapping">,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6325,7 +6325,28 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
63256325

63266326
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var,
63276327
options::OPT_fno_visibility_inlines_hidden_static_local_var);
6328-
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden);
6328+
6329+
// -fvisibility-global-new-delete-hidden is a deprecated spelling of
6330+
// -fvisibility-global-new-delete=force-hidden.
6331+
if (const Arg *A =
6332+
Args.getLastArg(options::OPT_fvisibility_global_new_delete_hidden)) {
6333+
D.Diag(diag::warn_drv_deprecated_arg)
6334+
<< A->getAsString(Args)
6335+
<< "-fvisibility-global-new-delete=force-hidden";
6336+
}
6337+
6338+
if (const Arg *A =
6339+
Args.getLastArg(options::OPT_fvisibility_global_new_delete_EQ,
6340+
options::OPT_fvisibility_global_new_delete_hidden)) {
6341+
if (A->getOption().matches(options::OPT_fvisibility_global_new_delete_EQ)) {
6342+
A->render(Args, CmdArgs);
6343+
} else {
6344+
assert(A->getOption().matches(
6345+
options::OPT_fvisibility_global_new_delete_hidden));
6346+
CmdArgs.push_back("-fvisibility-global-new-delete=force-hidden");
6347+
}
6348+
}
6349+
63296350
Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
63306351

63316352
if (Args.hasFlag(options::OPT_fnew_infallible,

clang/lib/Driver/ToolChains/PS4CPU.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,12 @@ void toolchains::PS4PS5Base::addClangTargetOptions(
359359

360360
CC1Args.push_back("-fno-use-init-array");
361361

362+
// Default to -fvisibility-global-new-delete=source for PS5.
363+
if (getTriple().isPS5() &&
364+
!DriverArgs.hasArg(options::OPT_fvisibility_global_new_delete_EQ,
365+
options::OPT_fvisibility_global_new_delete_hidden))
366+
CC1Args.push_back("-fvisibility-global-new-delete=source");
367+
362368
const Arg *A =
363369
DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass,
364370
options::OPT_fno_visibility_from_dllstorageclass);

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3216,10 +3216,13 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
32163216
Alloc->setLocalOwningModule(TheGlobalModuleFragment);
32173217
}
32183218

3219-
Alloc->addAttr(VisibilityAttr::CreateImplicit(
3220-
Context, LangOpts.GlobalAllocationFunctionVisibilityHidden
3221-
? VisibilityAttr::Hidden
3222-
: VisibilityAttr::Default));
3219+
if (LangOpts.hasGlobalAllocationFunctionVisibility())
3220+
Alloc->addAttr(VisibilityAttr::CreateImplicit(
3221+
Context, LangOpts.hasHiddenGlobalAllocationFunctionVisibility()
3222+
? VisibilityAttr::Hidden
3223+
: LangOpts.hasProtectedGlobalAllocationFunctionVisibility()
3224+
? VisibilityAttr::Protected
3225+
: VisibilityAttr::Default));
32233226

32243227
llvm::SmallVector<ParmVarDecl *, 3> ParamDecls;
32253228
for (QualType T : Params) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -emit-llvm -o - | FileCheck %s -DLINKAGE=dso_local
2+
// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=default -fvisibility-global-new-delete=force-hidden -emit-llvm -o - | FileCheck %s -DLINKAGE=hidden
3+
// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -fvisibility-global-new-delete=force-protected -emit-llvm -o - | FileCheck %s -DLINKAGE=protected
4+
// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -fvisibility-global-new-delete=force-default -emit-llvm -o - | FileCheck %s -DLINKAGE=dso_local
5+
// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-unknown-unknown -fvisibility=hidden -fvisibility-global-new-delete=source -emit-llvm -o - | FileCheck %s -DLINKAGE=hidden
6+
7+
namespace std {
8+
typedef __typeof__(sizeof(0)) size_t;
9+
struct nothrow_t {};
10+
}
11+
12+
// Definition which inherits visibility from the implicit compiler generated declaration.
13+
void operator delete(void*) throw() {}
14+
// CHECK: define [[LINKAGE]] void @_ZdlPv
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/// Check driver handling for "-fvisibility-global-new-delete-hidden" and "-fvisibility-global-new-delete=".
2+
3+
/// These options are not added by default.
4+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm %s 2>&1 | \
5+
// RUN: FileCheck -check-prefix=DEFAULTS %s
6+
// DEFAULTS-NOT: "-fvisibility-global-new-delete="
7+
// DEFAULTS-NOT: "-fvisibility-global-new-delete-hidden"
8+
9+
// DEFINE: %{implicit-check-nots} = --implicit-check-not=-fvisibility-global-new-delete= --implicit-check-not=-fvisibility-global-new-delete-hidden
10+
11+
/// "-fvisibility-global-new-delete=source" added by default for PS5.
12+
// RUN: %clang -### --target=x86_64-sie-ps5 -c -emit-llvm %s 2>&1 | \
13+
// RUN: FileCheck -check-prefix=PS5 %s
14+
// PS5: "-fvisibility-global-new-delete=source"
15+
16+
/// -fvisibility-global-new-delete-hidden added explicitly.
17+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm \
18+
// RUN: -fvisibility-global-new-delete-hidden %s 2>&1 | FileCheck -check-prefixes=VGNDH,DEPRECATED %s %{implicit-check-nots}
19+
// RUN: %clang -### --target=x86_64-sie-ps5 -c -emit-llvm \
20+
// RUN: -fvisibility-global-new-delete-hidden %s 2>&1 | FileCheck -check-prefixes=VGNDH,DEPRECATED %s %{implicit-check-nots}
21+
// DEPRECATED-DAG: clang: warning: argument '-fvisibility-global-new-delete-hidden' is deprecated, use '-fvisibility-global-new-delete=force-hidden' instead [-Wdeprecated]
22+
// VGNDH-DAG: "-fvisibility-global-new-delete=force-hidden"
23+
24+
/// -fvisibility-global-new-delete=force-hidden added explicitly.
25+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm \
26+
// RUN: -fvisibility-global-new-delete=force-hidden %s 2>&1 | FileCheck -check-prefixes=VGNDH %s %{implicit-check-nots}
27+
// RUN: %clang -### --target=x86_64-sie-ps5 -c -emit-llvm \
28+
// RUN: -fvisibility-global-new-delete=force-hidden %s 2>&1 | FileCheck -check-prefixes=VGNDH %s %{implicit-check-nots}
29+
30+
/// -fvisibility-global-new-delete=force-protected added explicitly.
31+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm \
32+
// RUN: -fvisibility-global-new-delete=force-protected %s 2>&1 | FileCheck -check-prefixes=VGNDP %s %{implicit-check-nots}
33+
// RUN: %clang -### --target=x86_64-sie-ps5 -c -emit-llvm \
34+
// RUN: -fvisibility-global-new-delete=force-protected %s 2>&1 | FileCheck -check-prefixes=VGNDP %s %{implicit-check-nots}
35+
// VGNDP-DAG: "-fvisibility-global-new-delete=force-protected"
36+
37+
/// -fvisibility-global-new-delete=force-default added explicitly.
38+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm \
39+
// RUN: -fvisibility-global-new-delete=force-default %s 2>&1 | FileCheck -check-prefixes=VGNDD %s %{implicit-check-nots}
40+
// RUN: %clang -### --target=x86_64-sie-ps5 -c -emit-llvm \
41+
// RUN: -fvisibility-global-new-delete=force-default %s 2>&1 | FileCheck -check-prefixes=VGNDD %s %{implicit-check-nots}
42+
// VGNDD-DAG: "-fvisibility-global-new-delete=force-default"
43+
44+
/// last specfied used: -fvisibility-global-new-delete-hidden.
45+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm \
46+
// RUN: -fvisibility-global-new-delete=force-default -fvisibility-global-new-delete=force-protected -fvisibility-global-new-delete-hidden %s 2>&1 | \
47+
// RUN: FileCheck -check-prefixes=VGNDH,DEPRECATED %s %{implicit-check-nots}
48+
49+
/// last specfied used: -fvisibility-global-new-delete=.
50+
// RUN: %clang -### --target=x86_64-unknown-unknown -c -emit-llvm \
51+
// RUN: -fvisibility-global-new-delete-hidden -fvisibility-global-new-delete=force-default -fvisibility-global-new-delete=force-protected %s 2>&1 | \
52+
// RUN: FileCheck -check-prefixes=VGNDP,DEPRECATED %s %{implicit-check-nots}

0 commit comments

Comments
 (0)