Skip to content

Commit

Permalink
Fix C++17 constexpr storage deprecation warnings
Browse files Browse the repository at this point in the history
This change introduces the symbol
ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
to guard redundant declarations of static constexpr data
members that are needed prior to C++17.

This change also introduces the symbol
ABSL_INTERNAL_CPLUSPLUS_LANG, which is supposed to be set
to the same value as __cplusplus, except it uses _MSVC_LANG
on MSVC so that the value is correct on MSVC.

Neither of these new symbols should be used outside of Abseil.

Fixes abseil#1191

PiperOrigin-RevId: 453923908
Change-Id: I1316c52c19fa0c168b93cced0c817e4cb7c9c862
  • Loading branch information
derekmauro authored and copybara-github committed Jun 9, 2022
1 parent 7383f34 commit 9eff978
Show file tree
Hide file tree
Showing 19 changed files with 87 additions and 22 deletions.
43 changes: 42 additions & 1 deletion absl/base/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@
#include <cstddef>
#endif // __cplusplus

// ABSL_INTERNAL_CPLUSPLUS_LANG
//
// MSVC does not set the value of __cplusplus correctly, but instead uses
// _MSVC_LANG as a stand-in.
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
//
// However, there are reports that MSVC even sets _MSVC_LANG incorrectly at
// times, for example:
// https://github.com/microsoft/vscode-cpptools/issues/1770
// https://reviews.llvm.org/D70996
//
// For this reason, this symbol is considered INTERNAL and code outside of
// Abseil must not use it.
#if defined(_MSVC_LANG)
#define ABSL_INTERNAL_CPLUSPLUS_LANG _MSVC_LANG
#elif defined(__cplusplus)
#define ABSL_INTERNAL_CPLUSPLUS_LANG __cplusplus
#endif

#if defined(__APPLE__)
// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED,
// __IPHONE_8_0.
Expand Down Expand Up @@ -807,6 +826,29 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1
#endif

// ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
//
// Prior to C++17, static constexpr variables defined in classes required a
// separate definition outside of the class body, for example:
//
// class Foo {
// static constexpr int kBar = 0;
// };
// constexpr int Foo::kBar;
//
// In C++17, these variables defined in classes are considered inline variables,
// and the extra declaration is redundant. Since some compilers warn on the
// extra declarations, ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL can be used
// conditionally ignore them:
//
// #ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
// constexpr int Foo::kBar;
// #endif
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG < 201703L
#define ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1
#endif

// `ABSL_INTERNAL_HAS_RTTI` determines whether abseil is being compiled with
// RTTI support.
#ifdef ABSL_INTERNAL_HAS_RTTI
Expand Down Expand Up @@ -868,5 +910,4 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_INTERNAL_HAVE_ARM_NEON 1
#endif


#endif // ABSL_BASE_CONFIG_H_
3 changes: 3 additions & 0 deletions absl/base/exception_safety_testing_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,10 @@ struct BasicGuaranteeWithExtraContracts : public NonNegative {

static constexpr int kExceptionSentinel = 9999;
};

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr int BasicGuaranteeWithExtraContracts::kExceptionSentinel;
#endif

TEST(ExceptionCheckTest, BasicGuaranteeWithExtraContracts) {
auto tester_with_val =
Expand Down
3 changes: 3 additions & 0 deletions absl/base/internal/cycleclock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <chrono> // NOLINT(build/c++11)

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/unscaledcycleclock.h"

namespace absl {
Expand All @@ -34,8 +35,10 @@ namespace base_internal {

#if ABSL_USE_UNSCALED_CYCLECLOCK

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr int32_t CycleClock::kShift;
constexpr double CycleClock::kFrequencyScale;
#endif

ABSL_CONST_INIT std::atomic<CycleClockSourceFunc>
CycleClock::cycle_clock_source_{nullptr};
Expand Down
2 changes: 2 additions & 0 deletions absl/base/internal/fast_type_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ struct FastTypeTag {
constexpr static char dummy_var = 0;
};

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
template <typename Type>
constexpr char FastTypeTag<Type>::dummy_var;
#endif

// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the
// passed-in type. These are meant to be good match for keys into maps or
Expand Down
3 changes: 3 additions & 0 deletions absl/base/internal/spinlock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <limits>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/atomic_hook.h"
#include "absl/base/internal/cycleclock.h"
#include "absl/base/internal/spinlock_wait.h"
Expand Down Expand Up @@ -66,12 +67,14 @@ void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock,
submit_profile_data.Store(fn);
}

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
// Static member variable definitions.
constexpr uint32_t SpinLock::kSpinLockHeld;
constexpr uint32_t SpinLock::kSpinLockCooperative;
constexpr uint32_t SpinLock::kSpinLockDisabledScheduling;
constexpr uint32_t SpinLock::kSpinLockSleeper;
constexpr uint32_t SpinLock::kWaitTimeMask;
#endif

// Uncommon constructors.
SpinLock::SpinLock(base_internal::SchedulingMode mode)
Expand Down
2 changes: 2 additions & 0 deletions absl/container/fixed_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,14 @@ class FixedArray {
Storage storage_;
};

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
template <typename T, size_t N, typename A>
constexpr size_t FixedArray<T, N, A>::kInlineBytesDefault;

template <typename T, size_t N, typename A>
constexpr typename FixedArray<T, N, A>::size_type
FixedArray<T, N, A>::inline_elements;
#endif

template <typename T, size_t N, typename A>
void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct(
Expand Down
3 changes: 3 additions & 0 deletions absl/container/internal/hashtablez_sampler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr int HashtablezInfo::kMaxStackDepth;
#endif

namespace {
ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{
Expand Down
2 changes: 2 additions & 0 deletions absl/container/internal/raw_hash_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = {
ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty,
ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty, ctrl_t::kEmpty};

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr size_t Group::kWidth;
#endif

// Returns "random" seed.
inline size_t RandomSeed() {
Expand Down
2 changes: 2 additions & 0 deletions absl/numeric/int128.cc
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ std::ostream& operator<<(std::ostream& os, int128 v) {
ABSL_NAMESPACE_END
} // namespace absl

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
namespace std {
constexpr bool numeric_limits<absl::uint128>::is_specialized;
constexpr bool numeric_limits<absl::uint128>::is_signed;
Expand Down Expand Up @@ -381,3 +382,4 @@ constexpr int numeric_limits<absl::int128>::max_exponent10;
constexpr bool numeric_limits<absl::int128>::traps;
constexpr bool numeric_limits<absl::int128>::tinyness_before;
} // namespace std
#endif
2 changes: 2 additions & 0 deletions absl/status/status.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ const std::string* Status::EmptyString() {
return &empty.str;
}

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr const char Status::kMovedFromString[];
#endif

const std::string* Status::MovedFromString() {
static std::string* moved_from_string = new std::string(kMovedFromString);
Expand Down
2 changes: 2 additions & 0 deletions absl/strings/cord.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ static CordRep* CordRepFromString(std::string&& src) {
// --------------------------------------------------------------------
// Cord::InlineRep functions

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr unsigned char Cord::InlineRep::kMaxInline;
#endif

inline void Cord::InlineRep::set_data(const char* data, size_t n) {
static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15");
Expand Down
2 changes: 2 additions & 0 deletions absl/strings/cord_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
namespace absl {
ABSL_NAMESPACE_BEGIN

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr size_t CordBuffer::kDefaultLimit;
constexpr size_t CordBuffer::kCustomLimit;
#endif

ABSL_NAMESPACE_END
} // namespace absl
4 changes: 3 additions & 1 deletion absl/strings/internal/cord_rep_btree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

constexpr size_t CordRepBtree::kMaxCapacity; // NOLINT: needed for c++ < c++17
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr size_t CordRepBtree::kMaxCapacity;
#endif

namespace {

Expand Down
4 changes: 3 additions & 1 deletion absl/strings/internal/cord_rep_ring.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ class CordRepRing::Filler {
index_type pos_;
};

constexpr size_t CordRepRing::kMaxCapacity; // NOLINT: needed for c++11
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr size_t CordRepRing::kMaxCapacity;
#endif

bool CordRepRing::IsValid(std::ostream& output) const {
if (capacity_ == 0) {
Expand Down
2 changes: 2 additions & 0 deletions absl/strings/internal/cordz_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ namespace cord_internal {

using ::absl::base_internal::SpinLockHolder;

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr int CordzInfo::kMaxStackDepth;
#endif

ABSL_CONST_INIT CordzInfo::List CordzInfo::global_list_{absl::kConstInit};

Expand Down
9 changes: 4 additions & 5 deletions absl/strings/internal/str_format/extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ std::string FlagsToString(Flags v) {
return s;
}

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL

#define ABSL_INTERNAL_X_VAL(id) \
constexpr absl::FormatConversionChar FormatConversionCharInternal::id;
ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, )
Expand All @@ -45,17 +47,14 @@ constexpr absl::FormatConversionChar FormatConversionCharInternal::kNone;
ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, )
#undef ABSL_INTERNAL_CHAR_SET_CASE

// NOLINTNEXTLINE(readability-redundant-declaration)
constexpr FormatConversionCharSet FormatConversionCharSetInternal::kStar;
// NOLINTNEXTLINE(readability-redundant-declaration)
constexpr FormatConversionCharSet FormatConversionCharSetInternal::kIntegral;
// NOLINTNEXTLINE(readability-redundant-declaration)
constexpr FormatConversionCharSet FormatConversionCharSetInternal::kFloating;
// NOLINTNEXTLINE(readability-redundant-declaration)
constexpr FormatConversionCharSet FormatConversionCharSetInternal::kNumeric;
// NOLINTNEXTLINE(readability-redundant-declaration)
constexpr FormatConversionCharSet FormatConversionCharSetInternal::kPointer;

#endif // ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL

bool FormatSinkImpl::PutPaddedString(string_view value, int width,
int precision, bool left) {
size_t space_remaining = 0;
Expand Down
4 changes: 3 additions & 1 deletion absl/strings/internal/string_constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ struct StringConstant {
"The input string_view must point to constant data.");
};

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
template <typename T>
constexpr absl::string_view StringConstant<T>::value; // NOLINT
constexpr absl::string_view StringConstant<T>::value;
#endif

// Factory function for `StringConstant` instances.
// It supports callables that have a constexpr default constructor and a
Expand Down
15 changes: 2 additions & 13 deletions absl/strings/string_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,11 @@ string_view::size_type string_view::find_last_not_of(
return npos;
}

// MSVC has non-standard behavior that implicitly creates definitions for static
// const members. These implicit definitions conflict with explicit out-of-class
// member definitions that are required by the C++ standard, resulting in
// LNK1169 "multiply defined" errors at link time. __declspec(selectany) asks
// MSVC to choose only one definition for the symbol it decorates. See details
// at https://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx
#ifdef _MSC_VER
#define ABSL_STRING_VIEW_SELECTANY __declspec(selectany)
#else
#define ABSL_STRING_VIEW_SELECTANY
#endif

ABSL_STRING_VIEW_SELECTANY
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
constexpr string_view::size_type string_view::npos;
ABSL_STRING_VIEW_SELECTANY
constexpr string_view::size_type string_view::kMaxSize;
#endif

ABSL_NAMESPACE_END
} // namespace absl
Expand Down
2 changes: 2 additions & 0 deletions absl/types/internal/conformance_profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ struct SyntacticConformanceProfileOf {
type##_support); \
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(bool, is_##type)

#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(default_constructible);
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_constructible);
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_constructible);
Expand All @@ -733,6 +734,7 @@ ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_equal_comparable);
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_than_comparable);
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(swappable);
ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(hashable);
#endif

#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF
#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL
Expand Down

0 comments on commit 9eff978

Please sign in to comment.