From: Richard Smith Date: Wed, 10 Jan 2018 23:08:26 +0000 (+0000) Subject: In C++17, when instantiating an out-of-line definition of an inline static data X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=48cc498f2d5b241d4f54cb61f8e23949ecb8070b;p=clang In C++17, when instantiating an out-of-line definition of an inline static data member, don't forget to instantiate the initializer too. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322236 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0d45835742..b8b74408cb 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4151,7 +4151,8 @@ void Sema::BuildVariableInstantiation( // it right away if the type contains 'auto'. if ((!isa(NewVar) && !InstantiatingVarTemplate && - !(OldVar->isInline() && OldVar->isThisDeclarationADefinition())) || + !(OldVar->isInline() && OldVar->isThisDeclarationADefinition() && + !NewVar->isThisDeclarationADefinition())) || NewVar->getType()->isUndeducedType()) InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs); diff --git a/test/CodeGenCXX/cxx1z-inline-variables.cpp b/test/CodeGenCXX/cxx1z-inline-variables.cpp index 2d16acd8a8..50eab3b706 100644 --- a/test/CodeGenCXX/cxx1z-inline-variables.cpp +++ b/test/CodeGenCXX/cxx1z-inline-variables.cpp @@ -58,14 +58,22 @@ template struct X { static int a; static inline int b; static int c; + static const int d; + static int e; }; // CHECK: @_ZN1XIiE1aE = linkonce_odr global i32 10 // CHECK: @_ZN1XIiE1bE = global i32 20 // CHECK-NOT: @_ZN1XIiE1cE +// CHECK: @_ZN1XIiE1dE = linkonce_odr constant i32 40 +// CHECK: @_ZN1XIiE1eE = linkonce_odr global i32 50 template<> inline int X::a = 10; int &use3 = X::a; template<> int X::b = 20; template<> inline int X::c = 30; +template constexpr int X::d = 40; +template inline int X::e = 50; +const int *use_x_int_d = &X::d; +const int *use_x_int_e = &X::e; template struct Y; template<> struct Y { diff --git a/test/SemaTemplate/cxx17-inline-variables.cpp b/test/SemaTemplate/cxx17-inline-variables.cpp index 9e6761ee57..7fc0aa8eee 100644 --- a/test/SemaTemplate/cxx17-inline-variables.cpp +++ b/test/SemaTemplate/cxx17-inline-variables.cpp @@ -16,3 +16,14 @@ namespace CompleteType { constexpr int n = X::value; } + +template struct A { + static const int n; + static const int m; + constexpr int f() { return n; } + constexpr int g() { return n; } +}; +template constexpr int A::n = sizeof(A) + sizeof(T); +template inline constexpr int A::m = sizeof(A) + sizeof(T); +static_assert(A().f() == 5); +static_assert(A().g() == 5);