aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/Decl.cpp12
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp15
2 files changed, 24 insertions, 3 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 7469e8b27f..5eb9e8501e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -459,9 +459,15 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// about whether containing classes have visibility attributes,
// and that's intentional.
if (TSK != TSK_ExplicitInstantiationDeclaration &&
- ConsiderGlobalVisibility && MD->isInlined() &&
- MD->getASTContext().getLangOptions().InlineVisibilityHidden)
- LV.setVisibility(HiddenVisibility);
+ ConsiderGlobalVisibility &&
+ MD->getASTContext().getLangOptions().InlineVisibilityHidden) {
+ // InlineVisibilityHidden only applies to definitions, and
+ // isInlined() only gives meaningful answers on definitions
+ // anyway.
+ const FunctionDecl *Def = 0;
+ if (MD->hasBody(Def) && Def->isInlined())
+ LV.setVisibility(HiddenVisibility);
+ }
// Note that in contrast to basically every other situation, we
// *do* apply -fvisibility to method declarations.
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index 69ce256025..7f92be2abf 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -64,3 +64,18 @@ void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
// CHECK: define available_externally void @_ZN2X1IfE2f2Ev
x3->f2();
}
+
+// rdar://problem/8614470
+namespace test1 {
+ struct __attribute__((visibility("default"))) A {
+ inline void foo();
+ ~A();
+ };
+
+ void test() {
+ A a;
+ a.foo();
+ }
+// CHECK: declare void @_ZN5test11A3fooEv
+// CHECK: declare void @_ZN5test11AD1Ev
+}