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 #include
d 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.)