summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2018-01-17 12:56:35 +0000
committerHans Wennborg <hans@hanshq.net>2018-01-17 12:56:35 +0000
commitacedccff1d6958d55a34a1d09b10f94177572723 (patch)
tree0e0f78567657de5a4ca4bdc33806240ed3bb28b4
parent06686ae9ac50d03925b14372223519d50dc968fd (diff)
downloadclang-acedccff1d6958d55a34a1d09b10f94177572723.tar.gz
Merging r322236:
------------------------------------------------------------------------ r322236 | rsmith | 2018-01-10 15:08:26 -0800 (Wed, 10 Jan 2018) | 3 lines 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/branches/release_60@322641 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--test/CodeGenCXX/cxx1z-inline-variables.cpp8
-rw-r--r--test/SemaTemplate/cxx17-inline-variables.cpp11
3 files changed, 21 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index ab68e7e671..9163fbc6f7 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4160,7 +4160,8 @@ void Sema::BuildVariableInstantiation(
// it right away if the type contains 'auto'.
if ((!isa<VarTemplateSpecializationDecl>(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<typename T> 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<int>::a = 10;
int &use3 = X<int>::a;
template<> int X<int>::b = 20;
template<> inline int X<int>::c = 30;
+template<typename T> constexpr int X<T>::d = 40;
+template<typename T> inline int X<T>::e = 50;
+const int *use_x_int_d = &X<int>::d;
+const int *use_x_int_e = &X<int>::e;
template<typename T> struct Y;
template<> struct Y<int> {
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<true>::value;
}
+
+template <typename T> struct A {
+ static const int n;
+ static const int m;
+ constexpr int f() { return n; }
+ constexpr int g() { return n; }
+};
+template <typename T> constexpr int A<T>::n = sizeof(A) + sizeof(T);
+template <typename T> inline constexpr int A<T>::m = sizeof(A) + sizeof(T);
+static_assert(A<int>().f() == 5);
+static_assert(A<int>().g() == 5);