Index: cfe/trunk/lib/Sema/SemaTemplate.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp +++ cfe/trunk/lib/Sema/SemaTemplate.cpp @@ -9173,10 +9173,8 @@ if (!HasNoEffect) { // Instantiate static data member or variable template. Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); - if (PrevTemplate) { - // Merge attributes. - ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes()); - } + // Merge attributes. + ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes()); if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateVariableDefinition(D.getIdentifierLoc(), Prev); } Index: cfe/trunk/test/SemaCXX/attr-on-explicit-template-instantiation.cpp =================================================================== --- cfe/trunk/test/SemaCXX/attr-on-explicit-template-instantiation.cpp +++ cfe/trunk/test/SemaCXX/attr-on-explicit-template-instantiation.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// PR39118 +// Make sure that attributes are properly applied to explicit template +// instantiations. + +#define HIDDEN __attribute__((__visibility__("hidden"))) +#define VISIBLE __attribute__((__visibility__("default"))) + +namespace ns HIDDEN { + struct A { }; + template struct B { static A a; }; + template A B::a; + + // CHECK: @_ZN2ns1BIiE1aE = weak_odr global + // CHECK-NOT: hidden + template VISIBLE A B::a; +} + +struct C { }; +template struct D { static C c; }; +template C D::c; + +// CHECK-DAG: @_ZN1DIiE1cB3TAGE +template __attribute__((abi_tag("TAG"))) C D::c;