[AST] Use -fvisibility value when ignoring -fv-i-h* inline static locals
Summary:
In r340386 we added code to give static locals in inline functions
default visibility. Instead, we should use the "default" visibility
passed on the command line, which could be hidden or protected, as GCC
does.
Some code bases use both -fvisibility=hidden and
-fvisibility-inlines-hidden to hide inline functions of classes that are
explicitly marked with default visibility.
Fixes PR39236
Reviewers: hans, thakis
Subscribers: eraman, llvm-commits
Differential Revision: https://reviews.llvm.org/D53052
llvm-svn: 344190
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index bcdbd3b..bf5e7a7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -725,7 +725,7 @@
// If we're paying attention to global visibility, apply
// -finline-visibility-hidden if this is an inline method.
if (useInlineVisibilityHidden(D))
- LV.mergeVisibility(HiddenVisibility, true);
+ LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
}
}
@@ -915,7 +915,7 @@
// Note that we do this before merging information about
// the class visibility.
if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D))
- LV.mergeVisibility(HiddenVisibility, true);
+ LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false);
}
// If this class member has an explicit visibility attribute, the only
@@ -1265,14 +1265,24 @@
// If a function is hidden by -fvisibility-inlines-hidden option and
// is not explicitly attributed as a hidden function,
// we should not make static local variables in the function hidden.
- if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
- !(!hasExplicitVisibilityAlready(computation) &&
- getExplicitVisibility(FD, computation))) {
- assert(cast<VarDecl>(D)->isStaticLocal());
- return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
- }
-
LV = getLVForDecl(FD, computation);
+ if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
+ !LV.isVisibilityExplicit()) {
+ assert(cast<VarDecl>(D)->isStaticLocal());
+ // If this was an implicitly hidden inline method, check again for
+ // explicit visibility on the parent class, and use that for static locals
+ // if present.
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
+ LV = getLVForDecl(MD->getParent(), computation);
+ if (!LV.isVisibilityExplicit()) {
+ Visibility globalVisibility =
+ computation.isValueVisibility()
+ ? Context.getLangOpts().getValueVisibilityMode()
+ : Context.getLangOpts().getTypeVisibilityMode();
+ return LinkageInfo(VisibleNoLinkage, globalVisibility,
+ /*visibilityExplicit=*/false);
+ }
+ }
}
if (!isExternallyVisible(LV.getLinkage()))
return LinkageInfo::none();