[llvm] r310475 - [Support] PR33388 - Fix formatv_object move constructor
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 10 14:26:49 PDT 2017
Should we merge this to 5.0?
On Wed, Aug 9, 2017 at 6:47 AM, Benoit Belley via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: belleyb
> Date: Wed Aug 9 06:47:01 2017
> New Revision: 310475
>
> URL: http://llvm.org/viewvc/llvm-project?rev=310475&view=rev
> Log:
> [Support] PR33388 - Fix formatv_object move constructor
>
> formatv_object currently uses the implicitly defined move constructor,
> but it is buggy. In typical use-cases, the problem doesn't show-up
> because all calls to the move constructor are elided. Thus, the buggy
> constructors are never invoked.
>
> The issue especially shows-up when code is compiled using the
> -fno-elide-constructors compiler flag. For instance, this is useful when
> attempting to collect accurate code coverage statistics.
>
> The exact issue is the following:
>
> The Parameters data member is correctly moved, thus making the
> parameters occupy a new memory location in the target
> object. Unfortunately, the default copying of the Adapters blindly
> copies the vector of pointers, leaving each of these pointers
> referencing the parameters in the original object instead of the copied
> one. These pointers quickly become dangling when the original object is
> deleted. This quickly leads to crashes.
>
> The solution is to update the Adapters pointers when performing a move.
> The copy constructor isn't useful for format objects and can thus be
> deleted.
>
> This resolves PR33388.
>
> Differential Revision: https://reviews.llvm.org/D34463
>
> Modified:
> llvm/trunk/include/llvm/Support/FormatVariadic.h
> llvm/trunk/unittests/Support/FormatVariadicTest.cpp
>
> Modified: llvm/trunk/include/llvm/Support/FormatVariadic.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FormatVariadic.h?rev=310475&r1=310474&r2=310475&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/FormatVariadic.h (original)
> +++ llvm/trunk/include/llvm/Support/FormatVariadic.h Wed Aug 9 06:47:01 2017
> @@ -94,6 +94,15 @@ public:
> Adapters.reserve(ParamCount);
> }
>
> + formatv_object_base(formatv_object_base const &rhs) = delete;
> +
> + formatv_object_base(formatv_object_base &&rhs)
> + : Fmt(std::move(rhs.Fmt)),
> + Adapters(), // Adapters are initialized by formatv_object
> + Replacements(std::move(rhs.Replacements)) {
> + Adapters.reserve(rhs.Adapters.size());
> + };
> +
> void format(raw_ostream &S) const {
> for (auto &R : Replacements) {
> if (R.Type == ReplacementType::Empty)
> @@ -149,6 +158,14 @@ public:
> Parameters(std::move(Params)) {
> Adapters = apply_tuple(create_adapters(), Parameters);
> }
> +
> + formatv_object(formatv_object const &rhs) = delete;
> +
> + formatv_object(formatv_object &&rhs)
> + : formatv_object_base(std::move(rhs)),
> + Parameters(std::move(rhs.Parameters)) {
> + Adapters = apply_tuple(create_adapters(), Parameters);
> + }
> };
>
> // \brief Format text given a format string and replacement parameters.
>
> Modified: llvm/trunk/unittests/Support/FormatVariadicTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/FormatVariadicTest.cpp?rev=310475&r1=310474&r2=310475&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/Support/FormatVariadicTest.cpp (original)
> +++ llvm/trunk/unittests/Support/FormatVariadicTest.cpp Wed Aug 9 06:47:01 2017
> @@ -553,6 +553,12 @@ TEST(FormatVariadicTest, Adapter) {
> formatv("{0,=34:X-}", fmt_repeat(fmt_pad(N, 1, 3), 5)).str());
> }
>
> +TEST(FormatVariadicTest, MoveConstructor) {
> + auto fmt = formatv("{0} {1}", 1, 2);
> + auto fmt2 = std::move(fmt);
> + std::string S = fmt2;
> + EXPECT_EQ("1 2", S);
> +}
> TEST(FormatVariadicTest, ImplicitConversions) {
> std::string S = formatv("{0} {1}", 1, 2);
> EXPECT_EQ("1 2", S);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list