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.

llvm-svn: 316310
This commit is contained in:
Richard Smith 2017-10-23 03:58:34 +00:00
parent 64cb997ce1
commit 8910fe699e
2 changed files with 17 additions and 7 deletions

View 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.

View 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;