public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/98283] New: decltype(auto) may be deduce static data member to wrong type
@ 2020-12-15  1:13 wuyongwei at gmail dot com
  2021-08-03  5:33 ` [Bug c++/98283] decltype(auto) may deduce a static data member to wrong type in a template pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: wuyongwei at gmail dot com @ 2020-12-15  1:13 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 98283
           Summary: decltype(auto) may be deduce static data member to
                    wrong type
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wuyongwei at gmail dot com
  Target Milestone: ---

The following code shows that `decltype(auto)` is deduced to the wrong type
when used in template code for an expression like `(var.static_data_member>)`.

```cpp
#include <cstddef>
#include <type_traits>
#include <utility>

template <typename T>
struct type_displayer;

#define TYPE_DISPLAY(x) type_displayer<decltype(x)> test_obj;

struct SkipField {};

struct TestSkip {
    template <typename T, std::size_t> struct FIELD;

    int value;
    static SkipField unused;

    template <typename T>
    struct FIELD<T, 0> {
        T &&obj;
        FIELD(T &&ref) : obj(std::forward<T>(ref))
        {
        }
        decltype(auto) value()
        {
            return (obj.value);
        }
        static constexpr const char *name()
        {
            return "value";
        }
    };

    template <typename T>
    struct FIELD<T, 0 + 1> {
        T &&obj;
        FIELD(T &&ref) : obj(std::forward<T>(ref))
        {
        }
        decltype(auto) value()
        {
            return (obj.unused);
        }
        decltype((obj.unused)) valueAlt()
        {
            return (obj.unused);
        }
        static constexpr const char *name()
        {
            return "unused";
        }
    };
};

int main()
{
    TestSkip s;
    // decltype((TestSkip::FIELD<TestSkip&, 0>(s).value()))    is int&
    // decltype((TestSkip::FIELD<TestSkip&, 1>(s).value()))    is SkipField,
but it should be SkipField&
    // decltype((TestSkip::FIELD<TestSkip&, 1>(s).valueAlt())) is SkipField&
}
```

This is a simplified usage scenario, where I want to use a macro to generate
code to emulate static reflection. Here is the problematic part:

```cpp
        decltype(auto) value()
        {
            return (obj.unused);
        }
```

This function returns `SkipField`, instead of the expected `SkipField&`. I have
verified that clang does what I want.

Currently I have to avoid `decltype(auto)` as a workaround:

```cpp
        decltype((obj.unused)) valueAlt()
        {
            return (obj.unused);
        }
```

(I used the macro TYPE_DISPLAY to check the type of an expression.)

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

end of thread, other threads:[~2023-05-07 15:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-15  1:13 [Bug c++/98283] New: decltype(auto) may be deduce static data member to wrong type wuyongwei at gmail dot com
2021-08-03  5:33 ` [Bug c++/98283] decltype(auto) may deduce a static data member to wrong type in a template pinskia at gcc dot gnu.org
2023-05-07 15:58 ` cvs-commit at gcc dot gnu.org
2023-05-07 15:58 ` ppalka 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).