I believe Helgrind does not understand modern GCC implementations of the
Meyers Singleton. You will see similar warnings for any non-trivial static
object.

See e.g. https://stackoverflow.com/q/44698412/

I vaguely recall this was discussed here before and deemed "hard to fix".
But I cannot seem to find that discussion.

 - Pat


On Mon, Mar 11, 2019 at 2:59 PM André Offringa <offri...@gmail.com> wrote:

> Hi all,
>
> I'm struggling with a helgrind error that I don't understand. I've
> stripped the code to a minimal example that shows the issue and pasted
> the code below. As far as I can tell, the code should be thread safe,
> and I've looked at the gcc assembly output, and I can't see anything
> wrong with it so, so far I don't suspect it is a gcc error (but I'm not
> certain).
>
> The helgrind error only appears when I compile with -O0, -O1 or -O2, not
> with -O3. Also, when I call "get_int_no_warning" instead of "get_int",
> no helgrind errors are reported.
>
> Would anybody be able to tell me if this is a helgrind false positive?
>
> I compile with gcc (Debian 8.3.0-2) 8.3.0 and am using valgrind-3.14.0
> from Debian testing.
>
> (the weird method is used in a codebase to create an instance of an
> object that is never destructed but isn't reported as leaked memory
> either -- it's a hack around some static initialization order problems).
>
> Source code:
>
> #include <new>
> #include <iostream>
> #include <vector>
> #include <thread>
> #include <memory>
>
> int* get_int()
> {
>    static std::aligned_storage_t<sizeof(int), alignof(int)> storage;
>
>    // The following line is pointed out in a helgrind warning:
>    // "Possible data race during read of size 8..."
>    // When using -O2, this conflicts with a previous write of size 8,
> also at this line...
>    static int* ptr = new (reinterpret_cast<int*>(&storage)) int();
>
>    return ptr; // But with -O0, the previous line conflicts with this
> return statement.
> }
>
> int* get_int_no_warning()
> {
>    static int x = 0;
>    return &x;
> }
>
> void test()
> {
>    volatile int* a = get_int();
> }
>
> int main()
> {
>    std::thread a(test), b(test);
>    a.join();
>    b.join();
> }
>
> Thanks,
> André
>
>
> _______________________________________________
> Valgrind-users mailing list
> Valgrind-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to