[PATCH] D24649: Treat instantiations of variable templates as definitions

Serge Pavlov via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 16 02:35:24 PDT 2016


sepavloff created this revision.
sepavloff added reviewers: rsmith, tra.
sepavloff added a subscriber: cfe-commits.

Current version of clang cannot build the program:
```
template<int n> int var;
int main(int argc, char *argv[]) {
  return var<0>;
}

```
as linker does not find `var<0>`, codegen treats it as declaration only.
However this program must build succesfully, because the template
declaration is a definition as none of the conditions mentioned in
[basic.def]p2 is met. With this change codegen generates definitions
for file level variable template specialization even if the declaration
does not contain an initializer.

https://reviews.llvm.org/D24649

Files:
  lib/CodeGen/CodeGenModule.cpp
  test/CodeGenCXX/dllexport.cpp
  test/CodeGenCXX/variable-templates.cpp

Index: test/CodeGenCXX/variable-templates.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/variable-templates.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -std=c++14 %s -triple=x86_64-linux -emit-llvm -o - | FileCheck %s
+
+// Unused template
+// CHECK-NOT: _Z6var_00ILi0EE
+template<int n> int var_00;
+
+// Definition without initializer
+// CHECK: @_Z6var_01ILi0EE = linkonce_odr global i32 0, comdat
+template<int n> int var_01;
+int use_01a() {
+  return var_01<0>;
+}
+int use_01b() {
+  return var_01<0>;
+}
+
+// Definitions without initializer combined with extern declaration
+
+// CHECK: @_Z6var_02ILi0EE = linkonce_odr global i32 0, comdat
+template<int n> extern int var_02;
+template<int n> int var_02;
+int use_02() {
+  return var_02<0>;
+}
+
+// CHECK: @_Z6var_03ILi0EE = linkonce_odr global i32 0, comdat
+template<int n> int var_03;
+template<int n> extern int var_03;
+int use_03() {
+  return var_03<0>;
+}
+
+// CHECK: @_Z6var_04ILi0EE = linkonce_odr global i32 0, comdat
+template<int n> extern int var_04;
+int use_04() {
+  return var_04<0>;
+}
+template<int n> int var_04;
+
+// CHECK: @_Z6var_05ILi0EE = linkonce_odr global i32 0, comdat
+template<int n> int var_05;
+int use_05() {
+  return var_05<0>;
+}
+template<int n> extern int var_05;
+
+
+int main(int argc, char *argv[]) {
+  return 0;
+}
Index: test/CodeGenCXX/dllexport.cpp
===================================================================
--- test/CodeGenCXX/dllexport.cpp
+++ test/CodeGenCXX/dllexport.cpp
@@ -108,8 +108,8 @@
 template<typename T> __declspec(dllexport) int VarTmplDef;
 INSTVAR(VarTmplDef<ExplicitInst_Exported>)
 
-// MSC-DAG: @"\01??$VarTmplImplicitDef at UImplicitInst_Exported@@@@3HA" = external dllexport global
-// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE          = external dllexport global
+// MSC-DAG: @"\01??$VarTmplImplicitDef at UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global
+// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE          = weak_odr dllexport global
 template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
 USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
 
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1609,7 +1609,11 @@
                            !VD->hasDefinition() &&
                            (VD->hasAttr<CUDAConstantAttr>() ||
                             VD->hasAttr<CUDADeviceAttr>());
-    if (!MustEmitForCuda &&
+    bool MustEmitVarInst = isa<VarTemplateSpecializationDecl>(VD) &&
+                           !VD->isStaticDataMember() &&
+                           !VD->hasDefinition() &&
+                           !VD->hasAttr<DLLImportAttr>();
+    if (!(MustEmitForCuda || MustEmitVarInst) &&
         VD->isThisDeclarationADefinition() != VarDecl::Definition &&
         !Context.isMSStaticDataMemberInlineDefinition(VD)) {
       // If this declaration may have caused an inline variable definition to


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24649.71603.patch
Type: text/x-patch
Size: 3096 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160916/713f9f6f/attachment-0001.bin>


More information about the cfe-commits mailing list