public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/94939] New: [9.2.1] invalid code generation in ternary op with static class member (undefined behaviour nearby?)
@ 2020-05-04  6:49 tobias.pankrath@ssw-trading.com
  2020-05-04  6:50 ` [Bug c++/94939] " tobias.pankrath@ssw-trading.com
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: tobias.pankrath@ssw-trading.com @ 2020-05-04  6:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94939

            Bug ID: 94939
           Summary: [9.2.1] invalid code generation in ternary op with
                    static class member (undefined behaviour nearby?)
           Product: gcc
           Version: 9.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tobias.pankrath@ssw-trading.com
  Target Milestone: ---

I've got the following classes, which are using the type_safe library
(https://github.com/foonathan/type_safe).

struct Old
{
    inline constexpr Old();
    constexpr Old(std::int64_t v)
        : storage(v)
    {}
    std::int64_t storage = -1;
    static const Old magic;
};

constexpr Old::Old() { storage = 0; }

constexpr Old Old::magic = Old(12);

struct OldDerived : Old
{
    constexpr OldDerived(Old old)
        : Old(old)
    {}
    constexpr OldDerived(std::int64_t v)
        : Old(v)
    {}
    auto get() { return storage; }
    static const OldDerived magic;
};

constexpr OldDerived OldDerived::magic = OldDerived(Old::magic);

struct New : public Old
{
    New() = default;
};

template<typename Strongtypedef, typename OldType_>
struct conversions
{
    using OldType = OldType_;
    const OldType& toOld() const
    {
        return static_cast<const OldType&>(
            static_cast<const Old&>(type_safe::get(static_cast<const
Strongtypedef&>(*this))));
    }
};

template<typename ST, typename OT_>
struct one_more_type : conversions<ST, OT_>
{};

struct NewDerived
    : type_safe::strong_typedef<NewDerived, New>
    , one_more_type<NewDerived, OldDerived>
{
    NewDerived() = default;
    NewDerived(std::int64_t value)
        : strong_typedef(New{{value}})
    {}
};

As a colleague already pointed out, conversions::toOld() might have
an illegal cast in it and maybe that is all to this. What I observe is the
following code prints 'VALUE IS 0' (in production: VALUE IS <GARBAGE>).

OldDerived
callee(bool b)
{
    NewDerived a = NewDerived{11};
    return b ? a.toOld() : OldDerived::magic;
}

__attribute_noinline__ void
caller_magic(bool b)
{
    OldDerived value = callee(b);
    std::cerr << "VALUE IS " << value.storage << std::endl;
}

void main()
{
    caller_magic(true);
}

And if I do not use OldDerived::magic, the following code prints correctly
'VALUE IS 11'.

OldDerived
callee_lit(bool b)
{
    NewDerived a = NewDerived{11};
    return b ? a.toOld() : OldDerived(12);
}

__attribute_noinline__ void
caller_lit(bool b)
{
    OldDerived value = callee_lit(b);
    std::cerr << "VALUE IS " << value.storage << std::endl;
}

void main()
{
    caller_lit(true);
}


Here is the code, including the parts from type_safe) inside the compiler
explorer: https://godbolt.org/z/TGB8Jg


Is it enough to fix the cast to make sure the code does what one expects?

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-18 22:44 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-04  6:49 [Bug c++/94939] New: [9.2.1] invalid code generation in ternary op with static class member (undefined behaviour nearby?) tobias.pankrath@ssw-trading.com
2020-05-04  6:50 ` [Bug c++/94939] " tobias.pankrath@ssw-trading.com
2020-05-04  6:58 ` rguenth at gcc dot gnu.org
2020-05-04  7:14 ` tobias.pankrath@ssw-trading.com
2021-07-18 22:44 ` pinskia at gcc dot gnu.org
2021-07-18 22:44 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).