]> granicus.if.org Git - clang/commitdiff
For better compatibility with C++11 and C++14, emit a nondiscardable definition
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 23 Oct 2017 03:58:34 +0000 (03:58 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 23 Oct 2017 03:58:34 +0000 (03:58 +0000)
of a static constexpr data member if it's defined 'constexpr' out of line, not
only if it's defined 'constexpr' in the class.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316310 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
test/CodeGenCXX/cxx1z-inline-variables.cpp

index 15aa4531b8cd747aa917a7dc14b1f3054ec46075..a7ff9e10e9da26f290872cafd2428769105a2551 100644 (file)
@@ -5635,14 +5635,14 @@ ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {
 
   // In almost all cases, it's a weak definition.
   auto *First = VD->getFirstDecl();
-  if (!First->isConstexpr() || First->isInlineSpecified() ||
-      !VD->isStaticDataMember())
+  if (First->isInlineSpecified() || !First->isStaticDataMember())
     return InlineVariableDefinitionKind::Weak;
 
   // If there's a file-context declaration in this translation unit, it's a
   // non-discardable definition.
   for (auto *D : VD->redecls())
-    if (D->getLexicalDeclContext()->isFileContext())
+    if (D->getLexicalDeclContext()->isFileContext() &&
+        !D->isInlineSpecified() && (D->isConstexpr() || First->isConstexpr()))
       return InlineVariableDefinitionKind::Strong;
 
   // If we've not seen one yet, we don't know.
index 183709373d12aa0b695cbc9101db2439fcd7dfd6..0d2ec92a7af8258517c69809114a25a59295668f 100644 (file)
@@ -31,18 +31,28 @@ struct compat {
   static constexpr int b = 2;
   static constexpr int c = 3;
   static inline constexpr int d = 4;
+  static const int e = 5;
+  static const int f = 6;
+  static const int g = 7;
 };
 const int &compat_use_before_redecl = compat::b;
 const int compat::a;
 const int compat::b;
 const int compat::c;
 const int compat::d;
+const int compat::e;
+constexpr int compat::f;
+constexpr inline int compat::g;
 const int &compat_use_after_redecl1 = compat::c;
 const int &compat_use_after_redecl2 = compat::d;
-// CHECK: @_ZN6compat1bE = weak_odr constant i32 2
-// CHECK: @_ZN6compat1aE = weak_odr constant i32 1
-// CHECK: @_ZN6compat1cE = weak_odr constant i32 3
-// CHECK: @_ZN6compat1dE = linkonce_odr constant i32 4
+const int &compat_use_after_redecl3 = compat::g;
+// CHECK-DAG: @_ZN6compat1bE = weak_odr constant i32 2
+// CHECK-DAG: @_ZN6compat1aE = weak_odr constant i32 1
+// CHECK-DAG: @_ZN6compat1cE = weak_odr constant i32 3
+// CHECK-DAG: @_ZN6compat1dE = linkonce_odr constant i32 4
+// CHECK-DAG: @_ZN6compat1eE = constant i32 5
+// CHECK-DAG: @_ZN6compat1fE = weak_odr constant i32 6
+// CHECK-DAG: @_ZN6compat1gE = linkonce_odr constant i32 7
 
 template<typename T> struct X {
   static int a;