summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2018-03-20 03:27:44 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2018-03-20 03:27:44 +0000
commit18b28a86c1bcf167ca7c53e94cdb4e2c2463c804 (patch)
tree7b4830889dd68d77acd3ad3faefaccbc764a3177
parent3e9462607e05b6a0b943d7bd4fb178ed5e44660a (diff)
downloadbcm5719-llvm-18b28a86c1bcf167ca7c53e94cdb4e2c2463c804.tar.gz
bcm5719-llvm-18b28a86c1bcf167ca7c53e94cdb4e2c2463c804.zip
Properly construct `inline` members without initializers
Digging through commit logs, it appears the checks in this block predate `inline` class variables. With them, we fail to emit dynamic initializers for members that don't have an explicit initializer, and we won't go out of our way to instantiate the class denoted by `Var->getType()`. Fixes PR35599. llvm-svn: 327945
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp4
-rw-r--r--clang/test/CodeGenCXX/cxx1z-inline-variables.cpp26
2 files changed, 29 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 6f04dedeed5..3cc37d086ab 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4202,7 +4202,9 @@ void Sema::InstantiateVariableInitializer(
Var->setInvalidDecl();
}
} else {
- if (Var->isStaticDataMember()) {
+ // `inline` variables are a definition and declaration all in one; we won't
+ // pick up an initializer from anywhere else.
+ if (Var->isStaticDataMember() && !Var->isInline()) {
if (!Var->isOutOfLine())
return;
diff --git a/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp b/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
index 50eab3b7061..938ebbbeb3a 100644
--- a/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
+++ b/clang/test/CodeGenCXX/cxx1z-inline-variables.cpp
@@ -111,3 +111,29 @@ int e = d<int>;
// CHECK-NOT: __cxa_guard_acquire(i64* @_ZGV1b)
// CHECK: call i32 @_Z1fv
// CHECK-NOT: __cxa_guard_release(i64* @_ZGV1b)
+
+namespace PR35599 {
+struct Marker1 {};
+struct Marker2 {};
+
+template <typename>
+struct Foo {
+ struct Bar { Bar(); };
+ inline static Bar bar;
+};
+
+void run() {
+ // All we want here are ODR uses. Anything that requires that the type is
+ // complete is uninteresting.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-value"
+ Foo<Marker1>::bar;
+#pragma clang diagnostic pop
+ static_cast<void>(Foo<Marker2>::bar);
+}
+
+// CHECK-LABEL: define {{.*}}global_var_init{{.*}}comdat
+// CHECK: call void @_ZN7PR355993FooINS_7Marker1EE3BarC1Ev
+// CHECK-LABEL: define {{.*}}global_var_init{{.*}}comdat
+// CHECK: call void @_ZN7PR355993FooINS_7Marker2EE3BarC1Ev
+}
OpenPOWER on IntegriCloud