public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression
@ 2012-02-13  0:34 solodon at mail dot com
  2012-02-13  9:18 ` [Bug c++/52224] " daniel.kruegler at googlemail dot com
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: solodon at mail dot com @ 2012-02-13  0:34 UTC (permalink / raw)
  To: gcc-bugs

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

             Bug #: 52224
           Summary: [C++0x] Generic operator gets pulled into compile-time
                    expression
    Classification: Unclassified
           Product: gcc
           Version: 4.6.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: solodon@mail.com


Created attachment 26644
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26644
Code reproducing bug

Hi,

I have a piece of code that crashes gcc 4.5.2 and runs out of template
instantiation depth in 4.6.1, while I believe it should be well formed. The
command line I used for both compilers is: g++ -std=c++0x gcc_bug_mini.cpp

#include <iostream>
#include <type_traits>

// I can have multiple my_... classes,
template <class T> struct my_class {}; 

// Which is why for convenience I introduce this predicate
template <typename T> struct is_mine                { enum { value = false };
};
template <typename T> struct is_mine<my_class<T>>   { enum { value = true }; };

// Note the use of || here, use of + would make things compile
template <typename E1, typename E2> 
struct either_is_mine 
{ enum { value = is_mine<E1>::value || is_mine<E2>::value }; };

// Generic || that should only be used when one of arguments is my_...
template <typename E1, typename E2> 
inline auto operator||(E1&& e1, E2&& e2) throw() -> typename
std::enable_if<either_is_mine<E1,E2>::value, int>::type;

template <typename E1, typename E2> 
auto test(E1&& e1, E2&& e2) -> typename
std::enable_if<either_is_mine<E1,E2>::value, int>::type;

int main()
{
    test(3,12);
}

The problem is in || in the definition of either_is_mine: for some reason the
generic operator enabled only when one of the arguments is from my_... set is
considered as a possible overload (note that there is no constexpr on generic
operator, just inline).

GCC in both cases is running under MinGW on Windows 7 laptop.

Thanks,
Yuriy


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

* [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
  2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
@ 2012-02-13  9:18 ` daniel.kruegler at googlemail dot com
  2012-02-13  9:26 ` daniel.kruegler at googlemail dot com
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-02-13  9:18 UTC (permalink / raw)
  To: gcc-bugs

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

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-02-13 09:18:40 UTC ---
I can confirm that for gcc 4.7.0 20120211 (experimental) as well. To ease
comparison with other compiler I rewrote it into fully C++03 compatible form,
also removing all library dependencies:

//---
template<bool, class>
struct enable_if {};

template<class T>
struct enable_if<true, T> { typedef T type; };

template <class T> struct my_class {};

template <typename T> struct is_mine               { enum { value = false }; };
template <typename T> struct is_mine<my_class<T> > { enum { value = true }; };

template <typename E1, typename E2>
struct either_is_mine
{ static const bool value = is_mine<E1>::value || is_mine<E2>::value; };

template <typename E1, typename E2>
typename enable_if<either_is_mine<E1, E2>::value, int>::type
operator||(E1 e1, E2 e2);

template <typename E1, typename E2>
typename enable_if<either_is_mine<E1, E2>::value, int>::type
test(E1 e1, E2 e2);

int main()
{
  test(3, 12);
}
//---

Comeau online processes it nicely, rejecting the code as expected. clang online
(3.0) runs into a similar endless loop, which becomes an immediate segmentation
fault, if the unnamed enums in the is_mine template are changed to named ones.
I removed both the exception specification and the inline specifier from the
operator|| overload, because they do not change the result.

The enums in the is_mine template lead to an infinite recursion, because of the
alternate dependency to operator|| overload. The first argument is 

int, 

the second argument is the enum type 

decltype(is_mine<int>::value), 

the third is the enum type 

decltype(is_mine<decltype(is_mine<int>::value)>::value),

etc. I'm unsure whether this is a design problem or a compiler problem, but
there is an easy workaround for this: Just replace the enums used within both
is_mine templates by static const bool. This prevents that endless recursion,
because there is no infinite type change going on.


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

* [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
  2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
  2012-02-13  9:18 ` [Bug c++/52224] " daniel.kruegler at googlemail dot com
@ 2012-02-13  9:26 ` daniel.kruegler at googlemail dot com
  2012-02-13 11:16 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-02-13  9:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-02-13 09:26:34 UTC ---
I condensed the test case further down to the following:

//---
template<bool, class> struct enable_if {};
template<class T> struct enable_if<true, T> { typedef T type; };

template <typename T> struct is_mine { enum { value = false }; };

template <typename E1, typename E2>
struct either_is_mine { static const bool value = is_mine<E1>::value ||
is_mine<E2>::value; };

template <typename E1, typename E2>
typename enable_if<either_is_mine<E1, E2>::value, int>::type
operator||(E1 e1, E2 e2);

template <typename E1, typename E2>
typename enable_if<either_is_mine<E1, E2>::value, int>::type
test(E1 e1, E2 e2);

const int n = sizeof(test(1, 2));
//---


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

* [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
  2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
  2012-02-13  9:18 ` [Bug c++/52224] " daniel.kruegler at googlemail dot com
  2012-02-13  9:26 ` daniel.kruegler at googlemail dot com
@ 2012-02-13 11:16 ` rguenth at gcc dot gnu.org
  2012-02-13 21:18 ` solodon at mail dot com
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: rguenth at gcc dot gnu.org @ 2012-02-13 11:16 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2012-02-13
     Ever Confirmed|0                           |1

--- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-02-13 11:15:22 UTC ---
Thus, confirmed.


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

* [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
  2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
                   ` (2 preceding siblings ...)
  2012-02-13 11:16 ` rguenth at gcc dot gnu.org
@ 2012-02-13 21:18 ` solodon at mail dot com
  2012-02-21 21:26 ` daniel.kruegler at googlemail dot com
  2012-02-21 22:01 ` paolo.carlini at oracle dot com
  5 siblings, 0 replies; 7+ messages in thread
From: solodon at mail dot com @ 2012-02-13 21:18 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Yuriy Solodkyy <solodon at mail dot com> 2012-02-13 21:17:36 UTC ---
Was wondering myself if that can be a design issue - here is a related report I
did earlier for VC++ 11:

https://connect.microsoft.com/VisualStudio/feedback/details/724557/vs11-compiler-stack-overflow-only-when-used-from-command-line

The weird thing there was that the compiler runs out of stack only when
compiled from command line, while when compiled from IDE (with same arguments)
it was behaving correctly.


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

* [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
  2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
                   ` (3 preceding siblings ...)
  2012-02-13 21:18 ` solodon at mail dot com
@ 2012-02-21 21:26 ` daniel.kruegler at googlemail dot com
  2012-02-21 22:01 ` paolo.carlini at oracle dot com
  5 siblings, 0 replies; 7+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-02-21 21:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-02-21 21:17:41 UTC ---
I just found this closed CWG issue:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#487

It seems that the compiler behaviour is indeed intended by the core language.
Based on this rationale this bug entry should be closed as invalid.


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

* [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
  2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
                   ` (4 preceding siblings ...)
  2012-02-21 21:26 ` daniel.kruegler at googlemail dot com
@ 2012-02-21 22:01 ` paolo.carlini at oracle dot com
  5 siblings, 0 replies; 7+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-02-21 22:01 UTC (permalink / raw)
  To: gcc-bugs

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

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID

--- Comment #6 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-02-21 21:51:49 UTC ---
Great.


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

end of thread, other threads:[~2012-02-21 21:52 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-13  0:34 [Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression solodon at mail dot com
2012-02-13  9:18 ` [Bug c++/52224] " daniel.kruegler at googlemail dot com
2012-02-13  9:26 ` daniel.kruegler at googlemail dot com
2012-02-13 11:16 ` rguenth at gcc dot gnu.org
2012-02-13 21:18 ` solodon at mail dot com
2012-02-21 21:26 ` daniel.kruegler at googlemail dot com
2012-02-21 22:01 ` paolo.carlini at oracle 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).