public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/108414] New: template meta programming
@ 2023-01-16  6:30 amewo22370 at gmail dot com
  2023-01-16  6:40 ` [Bug c++/108414] " pinskia at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: amewo22370 at gmail dot com @ 2023-01-16  6:30 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108414
           Summary: template meta programming
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amewo22370 at gmail dot com
  Target Milestone: ---

Created attachment 54276
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54276&action=edit
archive with source code and preprocessed files

gcc of version 12.2.0 and linux 5.15.83-1-lts

I have attached the source code. If you compile test code with line 36
commented out and line 37 uncommented, then the compiler gives an error. But if
you uncomment line 36 and comment out line 37, the compiler compiles the code
without errors, but the result is incorrect.

Description of the code: template alias 'template<std::size_t I, typename T>
using nth_type_t;' must return type with index I, that contains in type list
'T'.

Comilator commands: 
gcc -v -save-temps -std=c++20 -lstdc++ test_line36.cpp -o test_line36
gcc -v -save-temps -std=c++20 -lstdc++ test_line37.cpp -o test_line37

Also added attachments according to bug reporting instructions.

Compilation error with 'gcc -v -save-temps -std=c++20 -lstdc++ test_line37.cpp
-o test_line37':

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-build-config=bootstrap-lto --with-linker-hash-style=gnu
--with-system-zlib --enable-__cxa_atexit --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-o' 'test_line37'
'-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/cc1plus -E -quiet -v -D_GNU_SOURCE
test_line37.cpp -mtune=generic -march=x86-64 -std=c++20 -fpch-preprocess -o
test_line37.ii
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0

/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/x86_64-pc-linux-gnu

/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/backward
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-o' 'test_line37'
'-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/cc1plus -fpreprocessed test_line37.ii
-quiet -dumpbase test_line37.cpp -dumpbase-ext .cpp -mtune=generic
-march=x86-64 -std=c++20 -version -o test_line37.s
GNU C++20 (GCC) version 12.2.0 (x86_64-pc-linux-gnu)
        compiled by GNU C version 12.2.0, GMP version 6.2.1, MPFR version
4.1.0-p13, MPC version 1.2.1, isl version isl-0.25-GMP

warning: MPFR header version 4.1.0-p13 differs from library version 4.1.1-p1.
warning: MPC header version 1.2.1 differs from library version 1.3.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++20 (GCC) version 12.2.0 (x86_64-pc-linux-gnu)
        compiled by GNU C version 12.2.0, GMP version 6.2.1, MPFR version
4.1.0-p13, MPC version 1.2.1, isl version isl-0.25-GMP

warning: MPFR header version 4.1.0-p13 differs from library version 4.1.1-p1.
warning: MPC header version 1.2.1 differs from library version 1.3.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 402ce889a414e2a3abbbe3146fa0a6cb
test_line37.cpp: In substitution of ‘template<long unsigned int I, class T>
using nth_type_t = typename nth_type::type [with long unsigned int I = 0; T =
type_list<int, float, double>]’:
test_line37.cpp:49:36:   required from here
test_line37.cpp:41:7: error: no type named ‘type’ in ‘struct nth_type<0,
type_list<int, float, double> >’
   41 | using nth_type_t = typename nth_type<I, T>::type;
      |       ^~~~~~~~~~
test_line37.cpp: In substitution of ‘template<long unsigned int I, class T>
using nth_type_t = typename nth_type::type [with long unsigned int I = 1; T =
type_list<int, float, double>]’:
test_line37.cpp:50:36:   required from here
test_line37.cpp:41:7: error: no type named ‘type’ in ‘struct nth_type<1,
type_list<int, float, double> >’
test_line37.cpp: In substitution of ‘template<long unsigned int I, class T>
using nth_type_t = typename nth_type::type [with long unsigned int I = 2; T =
type_list<int, float, double>]’:
test_line37.cpp:51:36:   required from here
test_line37.cpp:41:7: error: no type named ‘type’ in ‘struct nth_type<2,
type_list<int, float, double> >’
test_line37.cpp: In function ‘int main()’:
test_line37.cpp:53:25: error: ‘elm0’ was not declared in this scope
   53 |     std::cout << typeid(elm0).name() << std::endl;
      |                         ^~~~
test_line37.cpp:54:25: error: ‘elm1’ was not declared in this scope
   54 |     std::cout << typeid(elm1).name() << std::endl;
      |                         ^~~~
test_line37.cpp:55:25: error: ‘elm2’ was not declared in this scope
   55 |     std::cout << typeid(elm2).name() << std::endl;
      |

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

* [Bug c++/108414] template meta programming
  2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
@ 2023-01-16  6:40 ` pinskia at gcc dot gnu.org
  2023-01-16  7:00 ` amewo22370 at gmail dot com
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-16  6:40 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |c++-lambda, rejects-valid

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
> using nth_element_t = typename decltype([]<typename T>(const indexed<I, T>&){return std::type_identity<T>{};}(make_indexer<Ts...>()))::type;

There are some known issue with lambda inside a decltype which seems like might
be causing issues here ...

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

* [Bug c++/108414] template meta programming
  2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
  2023-01-16  6:40 ` [Bug c++/108414] " pinskia at gcc dot gnu.org
@ 2023-01-16  7:00 ` amewo22370 at gmail dot com
  2023-01-16  9:35 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: amewo22370 at gmail dot com @ 2023-01-16  7:00 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Евгений Лисицын <amewo22370 at gmail dot com> ---
(In reply to Andrew Pinski from comment #1)
> > using nth_element_t = typename decltype([]<typename T>(const indexed<I, T>&){return std::type_identity<T>{};}(make_indexer<Ts...>()))::type;
> 
> There are some known issue with lambda inside a decltype which seems like
> might be causing issues here ...

interesting that 'typedef' and 'using' have different behavior

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

* [Bug c++/108414] template meta programming
  2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
  2023-01-16  6:40 ` [Bug c++/108414] " pinskia at gcc dot gnu.org
  2023-01-16  7:00 ` amewo22370 at gmail dot com
@ 2023-01-16  9:35 ` redi at gcc dot gnu.org
  2023-01-16  9:40 ` [Bug c++/108414] Incorrect pack expansion as argument to lambda redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2023-01-16  9:35 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:

using size_t = decltype(sizeof(0));
template<typename T> struct type_identity { using type = T; };
template<typename T, typename U> constexpr bool is_same_v = false;
template<typename T> constexpr bool is_same_v<T, T> = true;

template<typename... Ts>
struct type_list {};

template <size_t I, typename T>
struct indexed { using type = T; };

template <size_t I, typename ...Ts>
struct indexer;

template <size_t I, typename T, typename ...Ts>
struct indexer<I, T, Ts...> : indexed<I, T>, indexer<I+1, Ts...> {};

template <size_t I, typename T>
struct indexer<I, T> : indexed<I, T> {};

template <size_t I, typename ...Ts>
using nth_element_t = typename decltype([]<typename T>(const indexed<I,
T>&){return type_identity<T>{};}(indexer<0, Ts...>{}))::type;

template<size_t I, typename T>
struct nth_type;

template<size_t I, typename ... Ts>
struct nth_type< I, type_list<Ts...> >
{
#ifndef USING
  typedef nth_element_t<I, Ts...> type; // Incorrect result with it
#else
  using type = nth_element_t<I, Ts...>; // Compile error
#endif
};

template<size_t I, typename T>
using nth_type_t = typename nth_type<I, T>::type;

using list = type_list<int, float, double>;

using elm0 = nth_type_t<0, list>;
using elm1 = nth_type_t<1, list>;
using elm2 = nth_type_t<2, list>;

static_assert( is_same_v<elm0, int> );
static_assert( is_same_v<elm1, float> );
static_assert( is_same_v<elm2, double> );


Without -DUSING

nth.cc:47:16: error: static assertion failed
   47 | static_assert( is_same_v<elm1, float> );
      |                ^~~~~~~~~~~~~~~~~~~~~~
nth.cc:48:16: error: static assertion failed
   48 | static_assert( is_same_v<elm2, double> );
      |                ^~~~~~~~~~~~~~~~~~~~~~~


With -DUSING

nth.cc: In substitution of 'template<long unsigned int I, class T> using
nth_type_t = typename nth_type::type [with long unsigned int I = 0; T =
type_list<int, float, double>]':
nth.cc:42:32:   required from here
nth.cc:38:7: error: no type named 'type' in 'struct nth_type<0, type_list<int,
float, double> >'
   38 | using nth_type_t = typename nth_type<I, T>::type;
      |       ^~~~~~~~~~
nth.cc: In substitution of 'template<long unsigned int I, class T> using
nth_type_t = typename nth_type::type [with long unsigned int I = 1; T =
type_list<int, float, double>]':
nth.cc:43:32:   required from here
nth.cc:38:7: error: no type named 'type' in 'struct nth_type<1, type_list<int,
float, double> >'
nth.cc: In substitution of 'template<long unsigned int I, class T> using
nth_type_t = typename nth_type::type [with long unsigned int I = 2; T =
type_list<int, float, double>]':
nth.cc:44:32:   required from here
nth.cc:38:7: error: no type named 'type' in 'struct nth_type<2, type_list<int,
float, double> >'
nth.cc:46:26: error: 'elm0' was not declared in this scope
   46 | static_assert( is_same_v<elm0, int> );
      |                          ^~~~
nth.cc:46:16: error: template argument 1 is invalid
   46 | static_assert( is_same_v<elm0, int> );
      |                ^~~~~~~~~~~~~~~~~~~~
nth.cc:47:26: error: 'elm1' was not declared in this scope
   47 | static_assert( is_same_v<elm1, float> );
      |                          ^~~~
nth.cc:47:16: error: template argument 1 is invalid
   47 | static_assert( is_same_v<elm1, float> );
      |                ^~~~~~~~~~~~~~~~~~~~~~
nth.cc:48:26: error: 'elm2' was not declared in this scope
   48 | static_assert( is_same_v<elm2, double> );
      |                          ^~~~
nth.cc:48:16: error: template argument 1 is invalid
   48 | static_assert( is_same_v<elm2, double> );
      |                ^~~~~~~~~~~~~~~~~~~~~~~

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

* [Bug c++/108414] Incorrect pack expansion as argument to lambda
  2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
                   ` (2 preceding siblings ...)
  2023-01-16  9:35 ` redi at gcc dot gnu.org
@ 2023-01-16  9:40 ` redi at gcc dot gnu.org
  2023-03-27 10:13 ` yagreg7 at gmail dot com
  2024-04-13  8:16 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2023-01-16  9:40 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2023-01-16
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
            Summary|template meta programming   |Incorrect pack expansion as
                   |                            |argument to lambda

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This works with or without -DUSING when -DNAMED_FUNCTION is used:

using size_t = decltype(sizeof(0));
template<typename T> struct type_identity { using type = T; };
template<typename T, typename U> constexpr bool is_same_v = false;
template<typename T> constexpr bool is_same_v<T, T> = true;

template<typename... Ts>
struct type_list {};

template <size_t I, typename T>
struct indexed { using type = T; };

template <size_t I, typename ...Ts>
struct indexer;

template <size_t I, typename T, typename ...Ts>
struct indexer<I, T, Ts...> : indexed<I, T>, indexer<I+1, Ts...> {};

template <size_t I, typename T>
struct indexer<I, T> : indexed<I, T> {};

#ifndef NAMED_FUNCTION
template <size_t I, typename ...Ts>
using nth_element_t = typename decltype([]<typename T>(const indexed<I,
T>&){return type_identity<T>{};}(indexer<0, Ts...>{}))::type;
#else
template<size_t I, typename T> auto select(const indexed<I, T>&) { return
type_identity<T>{}; }
template <size_t I, typename ...Ts>
using nth_element_t = typename decltype(select<I>(indexer<0, Ts...>{}))::type;
#endif

template<size_t I, typename T>
struct nth_type;

template<size_t I, typename ... Ts>
struct nth_type< I, type_list<Ts...> >
{
#ifndef USING
  typedef nth_element_t<I, Ts...> type; // Incorrect result with it
#else
  using type = nth_element_t<I, Ts...>; // Compile error
#endif
};

template<size_t I, typename T>
using nth_type_t = typename nth_type<I, T>::type;

using list = type_list<int, float, double>;

using elm0 = nth_type_t<0, list>;
using elm1 = nth_type_t<1, list>;
using elm2 = nth_type_t<2, list>;

static_assert( is_same_v<elm0, int> );
static_assert( is_same_v<elm1, float> );
static_assert( is_same_v<elm2, double> );

So as Andrew said, the problem is the lambda in the decltype expression.

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

* [Bug c++/108414] Incorrect pack expansion as argument to lambda
  2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
                   ` (3 preceding siblings ...)
  2023-01-16  9:40 ` [Bug c++/108414] Incorrect pack expansion as argument to lambda redi at gcc dot gnu.org
@ 2023-03-27 10:13 ` yagreg7 at gmail dot com
  2024-04-13  8:16 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: yagreg7 at gmail dot com @ 2023-03-27 10:13 UTC (permalink / raw)
  To: gcc-bugs

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

Gregory Dushkin <yagreg7 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yagreg7 at gmail dot com

--- Comment #5 from Gregory Dushkin <yagreg7 at gmail dot com> ---
I have two more much shorter examples of this problem:
https://godbolt.org/z/EWb3ToK6E
https://godbolt.org/z/fh5Tjax1z

The first one reveals that inside of a concept `decltype` of a lambda that
comes via a type alias will be evaluated to `int` (revealed with `#if 0` and
`-fconcepts-diagnostics-depth=2`). With `#if 1` it produces

```
<source>:17:32: error: template argument 1 is invalid
   17 |     concept ConceptTest = std::same_as<GetArg<T>, PT>;
```

The second example is probably one of the shortest ones to reveal this problem.

Both compile successfully with `clang trunk` and `msvc v19.latest` but don't
with `gcc trunk`

It would be really nice to see this issue resolved to be able to create type
helpers without cluttering the `detail` namespace :)

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

* [Bug c++/108414] Incorrect pack expansion as argument to lambda
  2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
                   ` (4 preceding siblings ...)
  2023-03-27 10:13 ` yagreg7 at gmail dot com
@ 2024-04-13  8:16 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-04-13  8:16 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED
   Target Milestone|---                         |14.0

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Fixed on the trunk for GCC 14 by the recent lambda template patches.

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

end of thread, other threads:[~2024-04-13  8:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-16  6:30 [Bug c++/108414] New: template meta programming amewo22370 at gmail dot com
2023-01-16  6:40 ` [Bug c++/108414] " pinskia at gcc dot gnu.org
2023-01-16  7:00 ` amewo22370 at gmail dot com
2023-01-16  9:35 ` redi at gcc dot gnu.org
2023-01-16  9:40 ` [Bug c++/108414] Incorrect pack expansion as argument to lambda redi at gcc dot gnu.org
2023-03-27 10:13 ` yagreg7 at gmail dot com
2024-04-13  8:16 ` 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).