Commit c559574c authored by Hans Wennborg's avatar Hans Wennborg
Browse files

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.

------------------------------------------------------------------------

llvm-svn: 322641
parent 45bdca2f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);

+8 −0
Original line number Diff line number Diff line
@@ -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> {
+11 −0
Original line number Diff line number Diff line
@@ -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);