Currently, in bison's C++ parser template (`lalr.cc`), the `variant<>` struct's `build()` method uses placement-new in the form `new (...) T` to initialize a variant type. However, for POD variant types, this will leave the memory space uninitialized. If we subsequently tries to `::move` into a variant object in such state, the call can trigger clang's undefined behavior sanitizer due to accessing the uninitialized memory.
This attached patch changes the code to use the `new (...) T ()` form (note the parentheses at the end) instead, so that the memory space will be zero-initialized. commit cd47354652134067b144a3b5d2fdc51d35221420 Author: Jiahao Li <[email protected]> Date: Fri Aug 24 10:30:34 2018 -0700 Fixes uninitialized memory in variant<> Currently, in bison's C++ parser template (`lalr.cc`), the `variant<>` struct's `build()` method uses placement-new in the form `new (...) T` to initialize a variant type. However, for POD variant types, this will leave the memory space uninitialized. If we subsequently tries to `::move` into a variant object in such state, the call can trigger clang's undefined behavior sanitizer due to accessing the uninitialized memory. This commit changes the code to use the `new (...) T ()` form (note the parentheses at the end) instead, so that the memory space will be zero-initialized. diff --git a/data/variant.hh b/data/variant.hh index 1ffc5b26..8d0f06f6 100644 --- a/data/variant.hh +++ b/data/variant.hh @@ -122,7 +122,7 @@ m4_define([b4_variant_define], YYASSERT (!yytypeid_); YYASSERT (sizeof (T) <= S); yytypeid_ = & typeid (T);])[ - return *new (yyas_<T> ()) T; + return *new (yyas_<T> ()) T (); } /// Instantiate a \a T in here from \a t.
