I'm testing upgrading from GCC 9.3 to 10.2 and I'm seeing this new warning:
$ g++ --version x86_64-unknown-linux-gnu-g++ (GCC) 10.2.0 ... $ g++ -Wall -Werror -O2 -c -o stringop.o stringop.cpp In member function 'void LeafNode::markUpdate()', inlined from 'void applyTo(LeafNode*)' at stringop.cpp:45:21: stringop.cpp:37:33: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] 37 | void markUpdate() { flags() |= UPDATE; } | ~~~~~~~~^~~~~~~~~ stringop.cpp: In function 'void applyTo(LeafNode*)': stringop.cpp:34:7: note: at offset 0 to object 'LeafNode::<anonymous>' with size 4 declared here 34 | class LeafNode : public NodeWithPayload<LeafNodePayload> | ^~~~~~~~ cc1plus: all warnings being treated as errors It could well be that this code is dodgy; I take no responsibility for it :). It's part of a very tricky and performance- and memory- sensitive area of the software. I've stripped out tons of stuff and gotten it down to this, which is still probably not the minimal test case but is pretty small. If, for example, I take out the _sequence field in LeafNodePayload, it doesn't give any warnings. The repro case is provided below. If people think this is actually a bug I can file an issue. ----------------------------------------------------- nclude <cstddef> #include <cstdint> constexpr unsigned char UPDATE = 0x4; class Node { protected: static size_t actualSize(uint16_t keyLength, size_t alignment) { return alignment * (((offsetof(Node, key) + keyLength - 1) / alignment) + 1); } public: const uint16_t _keyLength; struct {} key; }; template<typename PAYLOAD> class NodeWithPayload : public Node { protected: PAYLOAD& getPayload() { return *(reinterpret_cast<PAYLOAD*>(reinterpret_cast<unsigned char*>(this) + Node::actualSize(_keyLength, alignof(PAYLOAD)))); } }; class LeafNodePayload { public: uint64_t _sequence; unsigned char _flags; }; class LeafNode : public NodeWithPayload<LeafNodePayload> { public: void markUpdate() { flags() |= UPDATE; } private: unsigned char& flags() { return getPayload()._flags; } }; void applyTo(LeafNode* node) { node->markUpdate(); }