Bug 66421 - G++ fails compilation when assigning tuple created with variadic template to auto variable
Summary: G++ fails compilation when assigning tuple created with variadic template to ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: 5.2
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
: 57565 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-06-04 20:42 UTC by Eugenio Bargiacchi
Modified: 2015-07-09 09:09 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.8.3, 4.9.2, 5.1.0, 6.0
Last reconfirmed: 2015-06-05 00:00:00


Attachments
File generated with -save-temps (57.94 KB, text/plain)
2015-06-04 20:42 UTC, Eugenio Bargiacchi
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Eugenio Bargiacchi 2015-06-04 20:42:15 UTC
Created attachment 35697 [details]
File generated with -save-temps

The following code contains two equivalent functions, one declaring a variable with auto and the other specifying the variable type explicitly. The function using auto fails to compile, although the two functions provided are equivalent. clang++ successfully compiles the code:

    #include <tuple>

    template <size_t N, typename T, typename... Args>
    struct DimTupleImpl {
        using type = typename DimTupleImpl<N-1, T, Args..., T>::type;
    };

    template <typename T, typename... Args>
    struct DimTupleImpl<0, T, Args...> {
        using type = std::tuple<Args...>;
    };

    // Tuple with N elements all of type T
    template <size_t N, typename T>
    struct DimTuple {
        using type = typename DimTupleImpl<N, T>::type;
    };

    template <typename... Params>
    void foo(Params... params) {
        auto tuple = std::make_tuple((size_t)params...);
    }

    template <typename... Params>
    void bar(Params... params) {
        typename DimTuple<sizeof...(Params), size_t>::type tuple = std::make_tuple((size_t)params...);
    }

    int main() {
        foo(1,2,3); // Fails, clang++ compiles it
        bar(1,2,3); // Compiles correctly
        return 0;
    }

# Compiled as: 

g++ -std=c++11 main.cpp

# Compiler output:

main.cpp: In instantiation of ‘void foo(Params ...) [with Params = {int, int, int}]’:
main.cpp:30:14:   required from here
main.cpp:21:51: error: conversion from ‘std::tuple<long unsigned int, long unsigned int, long unsigned int>’ to non-scalar type ‘std::tuple<long unsigned int>’ requested
     auto tuple = std::make_tuple((size_t)params...);
                                                   ^
# System:

Lubuntu 15.04

# Compiler info:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-10ubuntu13' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13)
Comment 1 Jonathan Wakely 2015-06-05 11:53:39 UTC
Reduced:

template<typename... T> struct tuple { };

template<typename... T> tuple<T...> make_tuple(T&&...) { return {}; }

template <typename... Params>
void foo(Params... params) {
    auto t = make_tuple((int)params...);
}

template <typename... Params>
void bar(Params... params) {
  tuple<decltype((int)params)...> t = make_tuple((int)params...);
}

int main() {
    foo(1,2,3); // Fails, clang++ compiles it
    bar(1,2,3); // Compiles correctly
}


t.cc: In instantiation of ‘void foo(Params ...) [with Params = {int, int, int}]’:
t.cc:16:14:   required from here
t.cc:7:39: error: conversion from ‘tuple<int, int, int>’ to non-scalar type ‘tuple<int>’ requested
     auto t = make_tuple((int)params...);
                                        ^
Comment 2 Nathan Sidwell 2015-06-07 23:50:13 UTC
Appears resolved in version r224163
Comment 3 Paolo Carlini 2015-07-08 14:49:27 UTC
Then let's add the testcase and close the bug.
Comment 4 Paolo Carlini 2015-07-08 16:04:55 UTC
Note that this is already fixed for 5.2.0 too.
Comment 5 paolo@gcc.gnu.org 2015-07-08 16:08:42 UTC
Author: paolo
Date: Wed Jul  8 16:08:10 2015
New Revision: 225563

URL: https://gcc.gnu.org/viewcvs?rev=225563&root=gcc&view=rev
Log:
2015-07-08  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/66421
	* g++.dg/cpp0x/auto45.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/auto45.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 6 Paolo Carlini 2015-07-08 16:09:07 UTC
Done.
Comment 7 Paolo Carlini 2015-07-09 09:09:44 UTC
*** Bug 57565 has been marked as a duplicate of this bug. ***