From ef34bcb258ffbf7a500bb715edced98fe6348676 Mon Sep 17 00:00:00 2001 From: Richard Smith <richard-llvm@metafoo.co.uk> Date: Mon, 23 Oct 2017 03:58:34 +0000 Subject: [PATCH] For better compatibility with C++11 and C++14, emit a nondiscardable definition 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 | 6 +++--- test/CodeGenCXX/cxx1z-inline-variables.cpp | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 15aa4531b8c..a7ff9e10e9d 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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. diff --git a/test/CodeGenCXX/cxx1z-inline-variables.cpp b/test/CodeGenCXX/cxx1z-inline-variables.cpp index 183709373d1..0d2ec92a7af 100644 --- a/test/CodeGenCXX/cxx1z-inline-variables.cpp +++ b/test/CodeGenCXX/cxx1z-inline-variables.cpp @@ -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; -- GitLab