phosek created this revision. phosek added reviewers: rsmith, rnk. Herald added a subscriber: cfe-commits.
When the global new and delete operators aren't declared, Clang provides and implicit declaration, but this declaration currently always uses the default visibility. This is a problem when the C++ library itself is being built with non-default visibility because the implicit declaration will force the new and delete operators to have the default visibility unlike the rest of the library. The existing workaround is to use assembly to enforce the visiblity: https://fuchsia.googlesource.com/zircon/+/master/system/ulib/zxcpp/new.cpp#108 but that solution is not always available, e.g. in the case of of libFuzzer which is using an internal version of libc++ that's also built with -fvisibility=hidden where the existing behavior is causing issues. This change modifies the implicit declaration of the global new and delete operators to respect the Clang visibility setting i.e. the -fvisibility= flag. Repository: rC Clang https://reviews.llvm.org/D53787 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExprCXX.cpp Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -2816,9 +2816,9 @@ // Global allocation functions should always be visible. Alloc->setVisibleDespiteOwningModule(); - // Implicit sized deallocation functions always have default visibility. - Alloc->addAttr( - VisibilityAttr::CreateImplicit(Context, VisibilityAttr::Default)); + Alloc->addAttr(VisibilityAttr::CreateImplicit( + Context, + getVisibilityAttr(Context.getLangOpts().getValueVisibilityMode()))); llvm::SmallVector<ParmVarDecl *, 3> ParamDecls; for (QualType T : Params) { Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -5195,6 +5195,18 @@ AFS_Both }; + static VisibilityAttr::VisibilityType getVisibilityAttr(clang::Visibility V) { + switch (V) { + case DefaultVisibility: + return VisibilityAttr::Default; + case HiddenVisibility: + return VisibilityAttr::Hidden; + case ProtectedVisibility: + return VisibilityAttr::Protected; + } + llvm_unreachable("unknown visibility!"); + }; + /// Finds the overloads of operator new and delete that are appropriate /// for the allocation. bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -2816,9 +2816,9 @@ // Global allocation functions should always be visible. Alloc->setVisibleDespiteOwningModule(); - // Implicit sized deallocation functions always have default visibility. - Alloc->addAttr( - VisibilityAttr::CreateImplicit(Context, VisibilityAttr::Default)); + Alloc->addAttr(VisibilityAttr::CreateImplicit( + Context, + getVisibilityAttr(Context.getLangOpts().getValueVisibilityMode()))); llvm::SmallVector<ParmVarDecl *, 3> ParamDecls; for (QualType T : Params) { Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -5195,6 +5195,18 @@ AFS_Both }; + static VisibilityAttr::VisibilityType getVisibilityAttr(clang::Visibility V) { + switch (V) { + case DefaultVisibility: + return VisibilityAttr::Default; + case HiddenVisibility: + return VisibilityAttr::Hidden; + case ProtectedVisibility: + return VisibilityAttr::Protected; + } + llvm_unreachable("unknown visibility!"); + }; + /// Finds the overloads of operator new and delete that are appropriate /// for the allocation. bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits