Author: steven_wu Date: Thu Apr 19 08:46:43 2018 New Revision: 330338 URL: http://llvm.org/viewvc/llvm-project?rev=330338&view=rev Log: [CXX] Templates specialization visibility can be wrong
Summary: Under some conditions, LinkageComputer can get the visibility for ClassTemplateSpecializationDecl wrong because it failed to find the Decl that has the explicit visibility. This fixes: llvm.org/bugs/pr36810 rdar://problem/38080953 Reviewers: rsmith, arphaman, doug.gregor Reviewed By: doug.gregor Subscribers: doug.gregor, cfe-commits Differential Revision: https://reviews.llvm.org/D44670 Added: cfe/trunk/test/CodeGenCXX/visibility-pr36810.cpp Modified: cfe/trunk/lib/AST/Decl.cpp Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=330338&r1=330337&r2=330338&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Thu Apr 19 08:46:43 2018 @@ -1092,9 +1092,18 @@ getExplicitVisibilityAux(const NamedDecl // If there wasn't explicit visibility there, and this is a // specialization of a class template, check for visibility // on the pattern. - if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND)) - return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(), - kind); + if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND)) { + // Walk all the template decl till this point to see if there are + // explicit visibility attributes. + const auto *TD = spec->getSpecializedTemplate()->getTemplatedDecl(); + while (TD != nullptr) { + auto Vis = getVisibilityOf(TD, kind); + if (Vis != None) + return Vis; + TD = TD->getPreviousDecl(); + } + return None; + } // Use the most recent declaration. if (!IsMostRecent && !isa<NamespaceDecl>(ND)) { Added: cfe/trunk/test/CodeGenCXX/visibility-pr36810.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility-pr36810.cpp?rev=330338&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/visibility-pr36810.cpp (added) +++ cfe/trunk/test/CodeGenCXX/visibility-pr36810.cpp Thu Apr 19 08:46:43 2018 @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx -std=c++11 -fvisibility hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx -DUNDEF_G -std=c++11 -fvisibility hidden -emit-llvm -o - %s -O2 -disable-llvm-passes | FileCheck %s + +namespace std { +template <class> +class __attribute__((__type_visibility__("default"))) shared_ptr { + template <class> friend class shared_ptr; +}; +} +struct dict; +#ifndef UNDEF_G +std::shared_ptr<dict> g; +#endif +class __attribute__((visibility("default"))) Bar; +template <class = std::shared_ptr<Bar>> +class __attribute__((visibility("default"))) i { + std::shared_ptr<int> foo() const; +}; + +// CHECK: define void @_ZNK1iISt10shared_ptrI3BarEE3fooEv +template <> std::shared_ptr<int> i<>::foo() const { + return std::shared_ptr<int>(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits