]> granicus.if.org Git - clang/commitdiff
Support attribute used in member funcs of class templates
authorRafael Auler <rafaelauler@fb.com>
Thu, 31 Jan 2019 09:38:31 +0000 (09:38 +0000)
committerRafael Auler <rafaelauler@fb.com>
Thu, 31 Jan 2019 09:38:31 +0000 (09:38 +0000)
Summary:
As PR17480 describes, clang does not support the used attribute
for member functions of class templates. This means that if the member
function is not used, its definition is never instantiated. This patch
changes clang to emit the definition if it has the used attribute.

Test Plan: Added a testcase

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D56928

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@352740 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp [new file with mode: 0644]

index 883a73f226642bf8977a787e3f3c9b1f714737cc..07533828dfd1b979f42bf4241479e874d4a00b48 100644 (file)
@@ -2175,6 +2175,20 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
     Owner->addDecl(Method);
   }
 
+  // PR17480: Honor the used attribute to instantiate member function
+  // definitions
+  if (Method->hasAttr<UsedAttr>()) {
+    if (const auto *A = dyn_cast<CXXRecordDecl>(Owner)) {
+      SourceLocation Loc;
+      if (const MemberSpecializationInfo *MSInfo =
+              A->getMemberSpecializationInfo())
+        Loc = MSInfo->getPointOfInstantiation();
+      else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(A))
+        Loc = Spec->getPointOfInstantiation();
+      SemaRef.MarkFunctionReferenced(Loc, Method);
+    }
+  }
+
   return Method;
 }
 
diff --git a/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp b/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
new file mode 100644 (file)
index 0000000..7d2062f
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// Check that PR17480 is fixed: __attribute__((used)) ignored in templated
+// classes
+namespace InstantiateUsedMemberDefinition {
+template <typename T>
+struct S {
+  int __attribute__((used)) f() {
+    return 0;
+  }
+};
+
+void test() {
+  // Check that InstantiateUsedMemberDefinition::S<int>::f() is defined
+  // as a result of the S class template implicit instantiation
+  // CHECK: define linkonce_odr i32 @_ZN31InstantiateUsedMemberDefinition1SIiE1fEv
+  S<int> inst;
+}
+} // namespace InstantiateUsedMemberDefinition