public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/53236] New: using declaration and base function template overloading
@ 2012-05-04 18:59 fpelliccioni at gmail dot com
  2012-05-05 17:41 ` [Bug c++/53236] " daniel.kruegler at googlemail dot com
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: fpelliccioni at gmail dot com @ 2012-05-04 18:59 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

             Bug #: 53236
           Summary: using declaration and base function template
                    overloading
    Classification: Unclassified
           Product: gcc
           Version: 4.7.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: fpelliccioni@gmail.com


Created attachment 27309
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27309
source code

The code in the attached source file must be rejected according to the 

[namespace.udecl] paragraph 15 (n3290)

When a using-declaration brings names from a base class into a derived class
scope, member functions and
member function templates in the derived class override and/or hide member
functions and member function
templates with the same name, parameter-type-list (8.3.5), cv-qualification,
and ref-qualifier (if any) in a
base class (rather than conflicting).



Tested with:

g++ 4.6.3 - Linux 3.2.0-24 x86
g++ 4.7.1 - Windows7 IA-64


Regards,
Fernando Pelliccioni.
fpelliccioni@gmail.com


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
@ 2012-05-05 17:41 ` daniel.kruegler at googlemail dot com
  2012-05-05 18:14 ` fabien at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-05 17:41 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

Daniel Krügler <daniel.kruegler at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.kruegler at
                   |                            |googlemail dot com

--- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-05 16:32:18 UTC ---
I agree that the code needs to be rejected, but I think the invalid expression
should be

ov.get<double>()

instead of

ov.get<int>()

as indicated by the code comment. The same defect also exists in 4.8.0 HEAD.


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
  2012-05-05 17:41 ` [Bug c++/53236] " daniel.kruegler at googlemail dot com
@ 2012-05-05 18:14 ` fabien at gcc dot gnu.org
  2012-05-05 19:17 ` daniel.kruegler at googlemail dot com
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: fabien at gcc dot gnu.org @ 2012-05-05 18:14 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

fabien at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fabien at gcc dot gnu.org

--- Comment #2 from fabien at gcc dot gnu.org 2012-05-05 18:04:26 UTC ---
The testcase does not seem to be reduced at the minimum. Would you mind
reducing it?


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
  2012-05-05 17:41 ` [Bug c++/53236] " daniel.kruegler at googlemail dot com
  2012-05-05 18:14 ` fabien at gcc dot gnu.org
@ 2012-05-05 19:17 ` daniel.kruegler at googlemail dot com
  2012-05-05 22:00 ` fpelliccioni at gmail dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-05 19:17 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #3 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-05 18:57:03 UTC ---
Reduced test-case:

//-----
template<typename, typename, typename>
struct enable_same
{};

template<typename T, typename U>
struct enable_same<T, T, U>
{
  typedef U type;
};

template <typename ...Ts>
struct other_variant
{
  void get(){}
};

template <typename T, typename ...Ts>
struct other_variant<T, Ts...> : other_variant<Ts...>
{
  T u;

  using other_variant<Ts...>::get;

  template <typename T2>
  typename enable_same<T, T2, T>::type
  get()    { return u; }
};

int main()
{
  other_variant<int, double> ov;
  ov.get<double>();
}
//-----

It should be added, that it is important that other_variant has a second
template argument of double here (e.g. 'bool' won't work): It seems as if
within the member template get of the  partial specialization T behaves as if
it were type double within this member declaration. The hypotheses becomes some
evidence, if we change the implementation of the get template as follows:

  template <typename T2>
  typename enable_same<T, T2, T>::type
  get()    {
    typename enable_same<T, double, bool>::type dummy;
    return u;
  }

This also is accepted, even though T is of type int.

The curiosity increases about the interpretation of the deduced type of 'T'
within the partial specialization, if we add seemingly contradictory typedefs
to the class body of the specialization as follows:

//---
template<typename, typename, typename>
struct enable_same
{};

template<typename T, typename U>
struct enable_same<T, T, U>
{
  typedef U type;
};

template <typename ...Ts>
struct other_variant
{
  void get(){}
};

template <typename T, typename ...Ts>
struct other_variant<T, Ts...> : other_variant<Ts...> // Line 18
{
  T u;

  typename enable_same<T, int, wchar_t>::type dummy1; // L. 22: Should be OK
  typename enable_same<T, double, char>::type dummy2; // Should be an error

  using other_variant<Ts...>::get;

  template <typename T2>
  typename enable_same<T, T2, T>::type
  get()    {
    typename enable_same<T, double, bool>::type dummy; // Should be an error
    return u;
  }
};

int main()
{
  other_variant<int, double> ov; // Line 37
  ov.get<double>();
}
//---

On gcc 4.8.0 20120429 (experimental) I get the following diagnostics:

18|  required from 'struct other_variant<int, double>'|
37|  required from here|
22|error: no type named 'type' in 'struct enable_same<double, int, wchar_t>'|
37|  required from here|
23|error: no type named 'type' in 'struct enable_same<int, double, char>'|
38|  required from here|
30|warning: unused variable 'dummy' [-Wunused-variable]|

Note that lines 22 and 23 describe the affected instantiations as

enable_same<double, int, wchar_t>

and

enable_same<int, double, char>

thus T seems to be once double and once int within the same instantiation -
quite amusing ;-)


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (2 preceding siblings ...)
  2012-05-05 19:17 ` daniel.kruegler at googlemail dot com
@ 2012-05-05 22:00 ` fpelliccioni at gmail dot com
  2012-05-05 22:01 ` fpelliccioni at gmail dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: fpelliccioni at gmail dot com @ 2012-05-05 22:00 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #4 from Fernando Pelliccioni <fpelliccioni at gmail dot com> 2012-05-05 21:58:53 UTC ---
Created attachment 27321
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27321
simplified source code version


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (3 preceding siblings ...)
  2012-05-05 22:00 ` fpelliccioni at gmail dot com
@ 2012-05-05 22:01 ` fpelliccioni at gmail dot com
  2012-05-05 22:17 ` fpelliccioni at gmail dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: fpelliccioni at gmail dot com @ 2012-05-05 22:01 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #5 from Fernando Pelliccioni <fpelliccioni at gmail dot com> 2012-05-05 22:00:05 UTC ---
Here is a simplified code -> "gcc_error_simple.cpp"
Shows two facets of the error.

See the comments in the attached file.


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (4 preceding siblings ...)
  2012-05-05 22:01 ` fpelliccioni at gmail dot com
@ 2012-05-05 22:17 ` fpelliccioni at gmail dot com
  2012-05-06 17:55 ` daniel.kruegler at googlemail dot com
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: fpelliccioni at gmail dot com @ 2012-05-05 22:17 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #6 from Fernando Pelliccioni <fpelliccioni at gmail dot com> 2012-05-05 22:01:23 UTC ---
// g++ -std=c++11 gcc_error_simple.cpp
// g++ -DWITH_USING_DECLARATION -std=c++11 gcc_error_simple.cpp

#include <iostream>
#include <type_traits>
#include <typeinfo>

template <typename T>
struct Base
{
    template <typename T2>
    typename std::enable_if<std::is_same<T, T2>::value, T>::type 
    get()
    {
    }
};

template <typename T>
struct Derived : Base<int>
{
    typedef Base<int> base;

#ifdef WITH_USING_DECLARATION
    using base::get;
#endif

    template <typename T2>
    typename std::enable_if<std::is_same<T, T2>::value, T>::type
    get()
    {
    }
};


int main( /* int argc, char* argv[] */ )
{
    Derived<double> d;

    auto xxx = d.get<double>();
    //std::cout << typeid(xxx).name() << std::endl;

    auto yyy = d.get<int>();        // #ifndef WITH_USING_DECLARATION ->
Compile-time error    -> GCC is behaving incorrectly. Base<int>::get<int>()
should not be hidden
                                                            // #ifdef 
WITH_USING_DECLARATION -> No Compile-time error -> GCC is behaving incorrectly.
Base<int>::get<int>() must be hidden.
    //std::cout << typeid(yyy).name() << std::endl;

    return 0;
}


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (5 preceding siblings ...)
  2012-05-05 22:17 ` fpelliccioni at gmail dot com
@ 2012-05-06 17:55 ` daniel.kruegler at googlemail dot com
  2012-05-07 13:27 ` fpelliccioni at gmail dot com
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-06 17:55 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #7 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-06 17:34:10 UTC ---
(In reply to comment #5)
> Here is a simplified code -> "gcc_error_simple.cpp"
> Shows two facets of the error.
> 
> See the comments in the attached file.

Fixed and simplified that code we have:

//---
template<typename, typename, typename>
struct enable_same
{};

template<typename T, typename U>
struct enable_same<T, T, U>
{
  typedef U type;
};

template <typename T>
struct Base
{
    T u;

    template <typename T2>
    typename enable_same<T, T2, T>::type
    get() { return u; }
};

template <typename T>
struct Derived : Base<int>
{
    typedef Base<int> base;

#ifdef WITH_USING_DECLARATION
    using base::get;
#endif

    template <typename T2>
    typename enable_same<T, T2, T>::type
    get() { return this->u;    } // Line 32
};

int main()
{
    Derived<double> d;
    d.get<double>();
    d.get<int>(); // Line 39
}
//---

Using gcc 4.8.0 20120429 (experimental) I see different results (I see the same
thing with your unchanged code taking into account that a function returning
no-void is expected to be rejected):

a) #ifndef WITH_USING_DECLARATION: The code is accepted as it should.
b) #ifdef WITH_USING_DECLARATION: The code is rejected as it should:

In function 'int main()':|
39|error: no matching function for call to 'Derived<double>::get()'|
39|note: candidate is:|
32|note: template<class T2> typename enable_same<T, T2, T>::type Derived::get()
[with T2 = T2; T = double]|
|32|note:   template argument deduction/substitution failed:|
39|  required from here|
32|error: no type named 'type' in 'struct enable_same<double, int, double>'|

Even though the third line of the diagnostics is a bit misleading it is
certainly correct the function call, because the base class get template is
hidden without the using-declaration. 

Summarizing, it seems that the variadic code is broken, not the non-variadic
case.


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (6 preceding siblings ...)
  2012-05-06 17:55 ` daniel.kruegler at googlemail dot com
@ 2012-05-07 13:27 ` fpelliccioni at gmail dot com
  2012-05-07 13:51 ` daniel.kruegler at googlemail dot com
  2012-05-07 14:00 ` fpelliccioni at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: fpelliccioni at gmail dot com @ 2012-05-07 13:27 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #8 from Fernando Pelliccioni <fpelliccioni at gmail dot com> 2012-05-07 13:24:02 UTC ---
Sorry, the comments were wrong.
Here the corrected code with proper comments.

Tested with GCC 4.7.1 and GCC 4.6.3


// g++ -std=c++0x gcc_error_simple.cpp
// g++ -DWITH_USING_DECLARATION -std=c++0x gcc_error_simple.cpp

#include <type_traits>

template <typename T>
struct Base
{
    template <typename T2>
    typename std::enable_if<std::is_same<T, T2>::value, T>::type
    get()
    {
        return T2();
    }
};

template <typename T>
struct Derived : Base<int>
{
    typedef Base<int> base;

#ifdef WITH_USING_DECLARATION
    using base::get;
#endif

    template <typename T2>
    typename std::enable_if<std::is_same<T, T2>::value, T>::type
    get()
    {
        return T2();
    }
};

int main( /* int argc, char* argv[] */ )
{
    Derived<double> d;

    auto xxx = d.get<double>();
    auto yyy = d.get<int>();    // #ifndef WITH_USING_DECLARATION ->
Compile-time error    -> GCC is behaving Correctly!!! Base<int>::get<int>() is
hidden!
                                // #ifdef  WITH_USING_DECLARATION -> No
Compile-time error -> GCC is behaving incorrectly. Base<int>::get<int>() must
be hidden.

    return 0;
}


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (7 preceding siblings ...)
  2012-05-07 13:27 ` fpelliccioni at gmail dot com
@ 2012-05-07 13:51 ` daniel.kruegler at googlemail dot com
  2012-05-07 14:00 ` fpelliccioni at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-07 13:51 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #9 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-07 13:50:10 UTC ---
(In reply to comment #8)
[..]
> Here the corrected code with proper comments.
[..]
>     auto yyy = d.get<int>();    // #ifndef WITH_USING_DECLARATION ->
> Compile-time error    -> GCC is behaving Correctly!!! Base<int>::get<int>() is
> hidden!
>                                 // #ifdef  WITH_USING_DECLARATION -> No
> Compile-time error -> GCC is behaving incorrectly. Base<int>::get<int>() must
> be hidden.

Its a mystery to me why get() should return an T2 when the return type is T,
but anyway: I cannot confirm your results for gcc 4.8.0 20120429
(experimental). Here the second case is correctly rejected.


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

* [Bug c++/53236] using declaration and base function template overloading
  2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
                   ` (8 preceding siblings ...)
  2012-05-07 13:51 ` daniel.kruegler at googlemail dot com
@ 2012-05-07 14:00 ` fpelliccioni at gmail dot com
  9 siblings, 0 replies; 11+ messages in thread
From: fpelliccioni at gmail dot com @ 2012-05-07 14:00 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236

--- Comment #10 from Fernando Pelliccioni <fpelliccioni at gmail dot com> 2012-05-07 13:58:38 UTC ---
(In reply to comment #9)
> (In reply to comment #8)
> [..]
> > Here the corrected code with proper comments.
> [..]
> >     auto yyy = d.get<int>();    // #ifndef WITH_USING_DECLARATION ->
> > Compile-time error    -> GCC is behaving Correctly!!! Base<int>::get<int>() is
> > hidden!
> >                                 // #ifdef  WITH_USING_DECLARATION -> No
> > Compile-time error -> GCC is behaving incorrectly. Base<int>::get<int>() must
> > be hidden.
> 
> Its a mystery to me why get() should return an T2 when the return type is T,
> but anyway: I cannot confirm your results for gcc 4.8.0 20120429
> (experimental). Here the second case is correctly rejected.

T and T2 are the same type. It is the same, could be... return T();

I'm glad that is resolved in 4.8.0
I can't test it, I don't have that version.

Thanks!


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

end of thread, other threads:[~2012-05-07 13:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-04 18:59 [Bug c++/53236] New: using declaration and base function template overloading fpelliccioni at gmail dot com
2012-05-05 17:41 ` [Bug c++/53236] " daniel.kruegler at googlemail dot com
2012-05-05 18:14 ` fabien at gcc dot gnu.org
2012-05-05 19:17 ` daniel.kruegler at googlemail dot com
2012-05-05 22:00 ` fpelliccioni at gmail dot com
2012-05-05 22:01 ` fpelliccioni at gmail dot com
2012-05-05 22:17 ` fpelliccioni at gmail dot com
2012-05-06 17:55 ` daniel.kruegler at googlemail dot com
2012-05-07 13:27 ` fpelliccioni at gmail dot com
2012-05-07 13:51 ` daniel.kruegler at googlemail dot com
2012-05-07 14:00 ` fpelliccioni at gmail dot com

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).