User account creation filtered due to spam.

Bug 54111 - function return type template deduction
Summary: function return type template deduction
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-28 07:45 UTC by Leonid Volnitsky
Modified: 2012-08-15 17:34 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
4 source code files. (392 bytes, application/x-compressed-tar)
2012-07-28 07:45 UTC, Leonid Volnitsky
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Leonid Volnitsky 2012-07-28 07:45:53 UTC
Created attachment 27882 [details]
4 source code files.

Possible regression. 

There are 4 version of slightly different versions of below code (file bug-u2.cc): 
 
-----------------------------------------------------
    #include <tuple>

    template<typename T, typename U> 
    U operator* (T x,  U& (*f)(T&) ) {  
        return (*f)(x);
    }; 

    int main() {
        std::tuple<int,int>  tpl(42,43);
        return   tpl * std::get<0,int,int>;
    }  
----------------------------------------------------

These 4 versions are combination of 2 variants:
- if template parameter U  or hardcoded type int is used (codes int or u) 
- if get<0,int,int>  or get<0> is used (codes 2 and 0)

4 version of above code are attached. 

For 3 versions of GCC that I have:

               453     471     480-pre 
--------------------------------------
bug-int0.cc    accp    accp    accp    
bug-int2.cc    accp    rej     rej     
bug-u0.cc      rej     rej     rej     
bug-u2.cc      accp    rej     rej   

It seems that gcc463 behave the same as 453.
Comment 1 Leonid Volnitsky 2012-08-02 04:02:27 UTC
I've just tested with gcc-463.    It accept/reject exactly the same as gcc-453.
Comment 2 Jonathan Wakely 2012-08-02 10:18:44 UTC
FWIW Clang 3.2 accepts bug-int?.cc and rejects bug-u?.cc
Comment 3 Leonid Volnitsky 2012-08-02 11:13:26 UTC
if in bug-int2.cc (and only in this file) to replace tuple with pair - it becomes accepted by any gcc version.
Comment 4 Leonid Volnitsky 2012-08-02 13:12:44 UTC
Please disregard my last message (about std::pair) - it was incorrect.
Comment 5 Leonid Volnitsky 2012-08-15 17:34:41 UTC
More combinatorics and more test (gcc-trunk, clang-trunk and gcc463).  Now everything in one file. 
-----------------------------------------------------------------

#include <tuple>
#include <utility>
using namespace std;


      int&  plaint_f(      int& x) {return x;};
const int&  plaint_f(const int& x) {return x;};

template<class T, class R>
R eval (T& x,  R& (*f)(T&)) { 
    return (*f)(x);
};

template<class T, class R>
R eval_const (const T& x,  const R& (*f)(const T&)) { 
    return (*f)(x);
};


template<class T, class R=int>
R eval_tuple_int (T& x,  R& (*f)(T&)) { 
    return (*f)(x);
};

template<class T, class R=int>
R eval_tuple_int_const (T& x,  const R& (*f)(const T&)) { 
    return (*f)(x);
};


template<class ...Ts, class R>
R eval_tuple (tuple<Ts...>& x,  R& (*f)(tuple<Ts...>&)) { 
    return (*f)(x);
};

template<class ...Ts, class R=int>
R eval_tuple_int (tuple<Ts...>& x,  R& (*f)(tuple<Ts...>&)) { 
    return (*f)(x);
};

template<class ...Ts, class R>
R eval_tuple_const (const tuple<Ts...>& x,  R& (*f)(const tuple<Ts...>&)) { 
    return (*f)(x);
};

template<class ...Ts, class R=int>
R eval_tuple_const_int (const tuple<Ts...>& x,  R& (*f)(const tuple<Ts...>&)) { 
    return (*f)(x);
};


int main() {

    //  int i42=42;
    //  return  eval(i42, plaint_f);
    //  OK

                        // 20.4.2.6  GET<..>(TUPLE) 
                        //  
                        //  template <size_t I, class... Types>
                        //  typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&) noexcept;
                        //  
                        //  template <size_t I, class... types>
                        //  typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&&) noexcept;
                        //  
                        //  template <size_t I, class... types>
                        //  typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>&) noexcept;

    
    tuple<int,int>  tpl(42,43);

    //////  INT eval..(TUPLE)
    
    //  return  eval_tuple_int(tpl, get<0,int,int>);
    //    gcc48-ERROR   types ‘tuple<_Elements ...>’ and ‘const pair<int, int>’ have incompatible cv-qualifiers
    //    gcc46-OK
    //    clang-OK
    
    //  return  eval_tuple_int(tpl, get<0>);
    //    gcc48-OK
    //    gcc46-OK
    //    clang-OK 

    //  return  eval_tuple_int_const(tpl, get<0,int,int>);
    //    gcc48-OK
    //    gcc46-OK
    //    clang-OK

    //  return  eval_tuple_int_const(tpl, get<0>);
    //    gcc48-OK
    //    gcc46-OK
    //    clang-OK
    
    
    //////  eval(TUPLE)
    
    //  return  eval(tpl, get<0>);
    //    gcc48-ERROR   couldn't deduce template parameter ‘R’
    //    gcc46-ERROR
    //    clang-ERROR   couldn't infer template argument 'R'

    //  return  eval(tpl, get<0,int,int>);
    //    gcc48-ERROR   could not resolve address from overloaded function ‘get<0, int, int>’   
    //    gcc46-OK
    //    clang-ERROR   couldn't infer template argument 'R'
    
    //  return  eval_const(tpl, get<0>);
    //    gcc48-ERROR   couldn't deduce template parameter ‘R’
    //    gcc46-ERROR
    //    clang-ERROR   couldn't infer template argument 'R'

    //  return  eval_const(tpl, get<0,int,int>);
    //    gcc48-OK
    //    gcc46-OK
    //    clang-ERROR   couldn't infer template argument 'R'
    
    //////  eval_tuple..(TUPLE)
    
    //  return  eval_tuple(tpl, get<0,int,int>);
    //    gcc48-ERROR   types ‘tuple<_Elements ...>’ and ‘const tuple<int, int>’ have incompatible cv-qualifiers
    //    gcc46-OK
    //    clang-OK
    
    //  return  eval_tuple_const(tpl, get<0,int,int>);
    //    gcc48-OK
    //    gcc46-OK
    //    clang-OK

    //  return  eval_tuple_const(tpl, get<0>);   
    //    gcc48-ERROR   couldn't deduce template parameter ‘R’
    //    gcc46-ERROR
    //    clang-ERROR

}