A hack / workaround for google/protobuf#1450, to get a stock version of Protocol Buffers 2.6.1 to work under UBSan. This is useful for (e.g.) building applications on Ubuntu 14.04 or 16.04, where you want to continue using the distro-provided protobuf library packaging instead of upgrading or patching the source.
There are two steps.
Replace every 16 in the generated .pb.cc files with this. For example, if you use GNU Make to generate your .pb.cc files:
%.pb.cc %.pb.h %_pb2.py: %.proto
protoc --cpp_out=. --python_out=. $<Then you can add a Perl one-liner to do the search-and-replace:
%.pb.cc %.pb.h %_pb2.py: %.proto
protoc --cpp_out=. --python_out=. $<
@# Hack: Work around https://github.com/google/protobuf/issues/1450
@# The ZR macros described there can work with 'this' and don't need to use
@# reinterpret_cast<>(0x10).
perl -pi -e 's/>\(16\)/>(this)/' $@Make sure that the following code is included in each of your generated .pb.cc files:
#include <google/protobuf/generated_message_reflection.h>
#undef GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Winvalid-offsetof\"") \
__builtin_offsetof(TYPE, FIELD) \
_Pragma("clang diagnostic pop") \
_Pragma("GCC diagnostic pop")
#endif(The best way to do this depends on your particular setup. E.g., you can use search-and-replace, as above, to #include a header with this code. In my case, each of our .pb.cc files is #included in a matching .cpp file, because some of our tools are very picky about file endings, so the .cpp files were a natural place to add this.)