Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for older gcc versions we still support #20463

Merged
merged 1 commit into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/test_cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
version: ['9.5', '13.1']
version: ['7.5', '9.1', '9.5', '13.1']
name: Linux GCC ${{ matrix.version }}
runs-on: ubuntu-latest
steps:
Expand All @@ -85,7 +85,7 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v4
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:7.1.2-${{ matrix.version }}-d9624f2aa83cba3eaf906f751d75b36aacb9aa82
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:7.1.2-${{ matrix.version }}-e78301df86b3e4c46ec9ac4d98be00e19305d8f3
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: cpp_linux/gcc-${{ matrix.version }}
bazel: test //pkg/... //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests
Expand Down Expand Up @@ -352,7 +352,7 @@ jobs:
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v4
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:7.1.2-12.2-d9624f2aa83cba3eaf906f751d75b36aacb9aa82
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:7.1.2-12.2-e78301df86b3e4c46ec9ac4d98be00e19305d8f3
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
entrypoint: bash
command: >-
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_upb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v4
with:
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:7.1.2-12.2-d9624f2aa83cba3eaf906f751d75b36aacb9aa82"
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:7.1.2-12.2-e78301df86b3e4c46ec9ac4d98be00e19305d8f3"
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: "upb-bazel-gcc"
bazel: >-
Expand Down
6 changes: 3 additions & 3 deletions src/google/protobuf/generated_message_tctable_lite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2717,11 +2717,11 @@ const char* TcParser::ParseOneMapEntry(
void* obj;
if (inner_tag == key_tag) {
type_card = map_info.key_type_card;
type_kind = map.type_info().key_type;
type_kind = map.type_info().key_type_kind();
obj = node->GetVoidKey();
} else {
type_card = map_info.value_type_card;
type_kind = map.type_info().value_type;
type_kind = map.type_info().value_type_kind();
obj = map.GetVoidValue(node);
}

Expand Down Expand Up @@ -2870,7 +2870,7 @@ PROTOBUF_NOINLINE const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) {
WriteMapEntryAsUnknown(msg, table, map, saved_tag, node, map_info);
} else {
// Done parsing the node, insert it.
switch (map.type_info().key_type) {
switch (map.type_info().key_type_kind()) {
case UntypedMapBase::TypeKind::kBool:
static_cast<KeyMapBase<bool>&>(map).InsertOrReplaceNode(
static_cast<KeyMapBase<bool>::KeyNode*>(node));
Expand Down
13 changes: 7 additions & 6 deletions src/google/protobuf/map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ void UntypedMapBase::ClearTableImpl(bool reset) {
};

const auto dispatch_key = [&](auto value_handler) {
if (type_info_.key_type < TypeKind::kString) {
if (type_info_.key_type_kind() < TypeKind::kString) {
loop(value_handler);
} else if (type_info_.key_type == TypeKind::kString) {
} else if (type_info_.key_type_kind() == TypeKind::kString) {
loop([=](NodeBase* node) {
static_cast<std::string*>(node->GetVoidKey())->~basic_string();
value_handler(node);
Expand All @@ -145,13 +145,13 @@ void UntypedMapBase::ClearTableImpl(bool reset) {
}
};

if (type_info_.value_type < TypeKind::kString) {
if (type_info_.value_type_kind() < TypeKind::kString) {
dispatch_key([](NodeBase*) {});
} else if (type_info_.value_type == TypeKind::kString) {
} else if (type_info_.value_type_kind() == TypeKind::kString) {
dispatch_key([&](NodeBase* node) {
GetValue<std::string>(node)->~basic_string();
});
} else if (type_info_.value_type == TypeKind::kMessage) {
} else if (type_info_.value_type_kind() == TypeKind::kMessage) {
dispatch_key([&](NodeBase* node) {
GetValue<MessageLite>(node)->DestroyInstance();
});
Expand Down Expand Up @@ -251,7 +251,8 @@ UntypedMapBase::TypeInfo UntypedMapBase::GetTypeInfoDynamic(
key_offsets.end, value_type, value_prototype_if_message, max_align);
return TypeInfo{
Narrow<uint16_t>(AlignTo(value_offsets.end, max_align, max_align)),
Narrow<uint8_t>(value_offsets.start), key_type, value_type};
Narrow<uint8_t>(value_offsets.start), static_cast<uint8_t>(key_type),
static_cast<uint8_t>(value_type)};
}

} // namespace internal
Expand Down
17 changes: 11 additions & 6 deletions src/google/protobuf/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,13 @@ class PROTOBUF_EXPORT UntypedMapBase {
uint16_t node_size;
// Equivalent to `offsetof(Node, kv.second)` in the derived type.
uint8_t value_offset;
TypeKind key_type : 4;
TypeKind value_type : 4;
uint8_t key_type : 4;
uint8_t value_type : 4;

TypeKind key_type_kind() const { return static_cast<TypeKind>(key_type); }
TypeKind value_type_kind() const {
return static_cast<TypeKind>(value_type);
}
};
static_assert(sizeof(TypeInfo) == 4);

Expand Down Expand Up @@ -474,7 +479,7 @@ class PROTOBUF_EXPORT UntypedMapBase {

template <typename F>
auto UntypedMapBase::VisitKeyType(F f) const {
switch (type_info_.key_type) {
switch (type_info_.key_type_kind()) {
case TypeKind::kBool:
return f(std::enable_if<true, bool>{});
case TypeKind::kU32:
Expand All @@ -494,7 +499,7 @@ auto UntypedMapBase::VisitKeyType(F f) const {

template <typename F>
auto UntypedMapBase::VisitValueType(F f) const {
switch (type_info_.value_type) {
switch (type_info_.value_type_kind()) {
case TypeKind::kBool:
return f(std::enable_if<true, bool>{});
case TypeKind::kU32:
Expand Down Expand Up @@ -1446,8 +1451,8 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
return internal::UntypedMapBase::TypeInfo{
sizeof(Node),
PROTOBUF_FIELD_OFFSET(Node, kv.second),
internal::UntypedMapBase::StaticTypeKind<Key>(),
internal::UntypedMapBase::StaticTypeKind<T>(),
static_cast<uint8_t>(internal::UntypedMapBase::StaticTypeKind<Key>()),
static_cast<uint8_t>(internal::UntypedMapBase::StaticTypeKind<T>()),
};
}

Expand Down
53 changes: 30 additions & 23 deletions src/google/protobuf/map_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,32 @@ TEST(MapTest, SizeTypeIsSizeT) {
(void)x;
}

using KeyTypes = void (*)(bool, int32_t, uint32_t, int64_t, uint64_t,
std::string);
// Some arbitrary proto enum.
using SomeEnum = proto2_unittest::TestAllTypes::NestedEnum;
using ValueTypes = void (*)(bool, int32_t, uint32_t, int64_t, uint64_t, float,
double, std::string, SomeEnum,
proto2_unittest::TestEmptyMessage,
proto2_unittest::TestAllTypes);

TEST(MapTest, StaticTypeKindWorks) {
using UMB = UntypedMapBase;
EXPECT_EQ(UMB::TypeKind::kBool, UMB::StaticTypeKind<bool>());
EXPECT_EQ(UMB::TypeKind::kU32, UMB::StaticTypeKind<int32_t>());
EXPECT_EQ(UMB::TypeKind::kU32, UMB::StaticTypeKind<uint32_t>());
EXPECT_EQ(UMB::TypeKind::kU32, UMB::StaticTypeKind<SomeEnum>());
EXPECT_EQ(UMB::TypeKind::kU64, UMB::StaticTypeKind<int64_t>());
EXPECT_EQ(UMB::TypeKind::kU64, UMB::StaticTypeKind<uint64_t>());
EXPECT_EQ(UMB::TypeKind::kString, UMB::StaticTypeKind<std::string>());
EXPECT_EQ(UMB::TypeKind::kMessage,
UMB::StaticTypeKind<proto2_unittest::TestAllTypes>());
}

#if !defined(__GNUC__) || defined(__clang__) || PROTOBUF_GNUC_MIN(9, 4)
// Parameter pack expansion bug before GCC 8.2:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85305

template <typename F, typename... Key, typename... Value>
void TestAllKeyValueTypes(void (*)(Key...), void (*)(Value...), F f) {
(
Expand All @@ -319,15 +345,6 @@ void TestAllKeyValueTypes(void (*)(Key...), void (*)(Value...), F f) {
...);
}

using KeyTypes = void (*)(bool, int32_t, uint32_t, int64_t, uint64_t,
std::string);
// Some arbitrary proto enum.
using SomeEnum = proto2_unittest::TestAllTypes::NestedEnum;
using ValueTypes = void (*)(bool, int32_t, uint32_t, int64_t, uint64_t, float,
double, std::string, SomeEnum,
proto2_unittest::TestEmptyMessage,
proto2_unittest::TestAllTypes);

TEST(MapTest, StaticTypeInfoMatchesDynamicOne) {
TestAllKeyValueTypes(KeyTypes(), ValueTypes(), [](auto key, auto value) {
using Key = decltype(key);
Expand All @@ -338,27 +355,15 @@ TEST(MapTest, StaticTypeInfoMatchesDynamicOne) {
}
const auto type_info = MapTestPeer::GetTypeInfo<Map<Key, Value>>();
const auto dyn_type_info = internal::UntypedMapBase::GetTypeInfoDynamic(
type_info.key_type, type_info.value_type, value_prototype);
type_info.key_type_kind(), type_info.value_type_kind(),
value_prototype);
EXPECT_EQ(dyn_type_info.node_size, type_info.node_size);
EXPECT_EQ(dyn_type_info.value_offset, type_info.value_offset);
EXPECT_EQ(dyn_type_info.key_type, type_info.key_type);
EXPECT_EQ(dyn_type_info.value_type, type_info.value_type);
});
}

TEST(MapTest, StaticTypeKindWorks) {
using UMB = UntypedMapBase;
EXPECT_EQ(UMB::TypeKind::kBool, UMB::StaticTypeKind<bool>());
EXPECT_EQ(UMB::TypeKind::kU32, UMB::StaticTypeKind<int32_t>());
EXPECT_EQ(UMB::TypeKind::kU32, UMB::StaticTypeKind<uint32_t>());
EXPECT_EQ(UMB::TypeKind::kU32, UMB::StaticTypeKind<SomeEnum>());
EXPECT_EQ(UMB::TypeKind::kU64, UMB::StaticTypeKind<int64_t>());
EXPECT_EQ(UMB::TypeKind::kU64, UMB::StaticTypeKind<uint64_t>());
EXPECT_EQ(UMB::TypeKind::kString, UMB::StaticTypeKind<std::string>());
EXPECT_EQ(UMB::TypeKind::kMessage,
UMB::StaticTypeKind<proto2_unittest::TestAllTypes>());
}

template <typename LHS, typename RHS>
void TestEqPtr(LHS* lhs, RHS* rhs) {
// To silence some false positive compiler errors in gcc 9.5
Expand Down Expand Up @@ -428,6 +433,8 @@ TEST(MapTest, VisitAllNodesUsesTheRightTypesOnAllNodes) {
});
}

#endif

TEST(MapTest, IteratorNodeFieldIsNullPtrAtEnd) {
Map<int, int> map;
EXPECT_EQ(internal::UntypedMapIterator::FromTyped(map.cbegin()).node_,
Expand Down
5 changes: 4 additions & 1 deletion src/google/protobuf/map_test.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2389,7 +2389,10 @@ class MyMapEntry
constexpr MyMapEntry()
: MyMapEntry::MapEntry(static_cast<ClassData*>(nullptr)) {}
MyMapEntry(Arena* arena) : MyMapEntry::MapEntry(arena, nullptr) {}
const ClassData* GetClassData() const { ABSL_CHECK(false); }
const ClassData* GetClassData() const {
ABSL_CHECK(false);
return nullptr;
}
static bool ValidateKey(void*) { return true; }
static bool ValidateValue(void*) { return true; }
};
Expand Down
Loading