public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1)
@ 2012-06-27 18:43 exa7z at live dot com
  2012-06-27 22:30 ` [Bug c++/53788] " daniel.kruegler at googlemail dot com
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: exa7z at live dot com @ 2012-06-27 18:43 UTC (permalink / raw)
  To: gcc-bugs

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

             Bug #: 53788
           Summary: C++11 decltype sfinae static member function check
                    (4.7.1)
    Classification: Unclassified
           Product: gcc
           Version: 4.7.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: exa7z@live.com


Greetings all. The following code should *not* compile (one of the ways for
detecting the presence or not of a static member function), because of a typo I
did in T/X substitution in the check function template:

Here is the testcase:
/* BEGIN TESTCASE */

#include <cstdio>
#include <type_traits>

template<typename T>
struct has_static {

    // NOTICE THE T/X substitution error, T::fun() should have been X::fun()
    // thanks to dgregor in http://llvm.org/bugs/show_bug.cgi?id=13223
    template<typename X>
    static std::true_type check(X*, decltype(T::fun())* = 0);

    static std::false_type check(...);

    typedef decltype(check((T*)(0))) _tmp;

    static const bool value = _tmp::value;
};

struct test {
    int fun() { return 0; }
};

int main() {
    printf("%d\n", has_static<test>::value);
    return(0);
}
/* END TESTCASE */

used: g++ (GCC) 4.7.1 with --std=c++0x

According to dgregor's reply in the aforementioned llvm bugzilla entry, clang
is right to not compile this while g++ tacitly accepts it before its time (from
4.5.1 to 4.7.1 at least). Is this something requiring fixing?

thanks.


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
@ 2012-06-27 22:30 ` daniel.kruegler at googlemail dot com
  2012-06-28  9:45 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-06-27 22:30 UTC (permalink / raw)
  To: gcc-bugs

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

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-06-27 22:30:33 UTC ---
The problem also persists in gcc 4.8.0 20120624 (experimental).

Simplified example free from library dependencies:

struct t { static const bool value = true; };
struct f { static const bool value = false; };

template<typename T>
struct has_static {
  template<typename X>
  static t check(X*, decltype(T::fun())* = 0);
  static f check(...);

  typedef decltype(check((T*)(0))) ret;
  static const bool value = ret::value;
};

struct test { int fun() { return 0; } };

bool b = has_static<test>::value;


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
  2012-06-27 22:30 ` [Bug c++/53788] " daniel.kruegler at googlemail dot com
@ 2012-06-28  9:45 ` redi at gcc dot gnu.org
  2012-06-28 10:36 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-28  9:45 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-28 09:44:50 UTC ---
(In reply to comment #0)
> Greetings all. The following code should *not* compile

I'm not convinced the standard *requires* it to be rejected.


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
  2012-06-27 22:30 ` [Bug c++/53788] " daniel.kruegler at googlemail dot com
  2012-06-28  9:45 ` redi at gcc dot gnu.org
@ 2012-06-28 10:36 ` redi at gcc dot gnu.org
  2012-06-28 17:37 ` exa7z at live dot com
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2012-06-28 10:36 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2012-06-28
     Ever Confirmed|0                           |1

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-28 10:36:29 UTC ---
Here's a C++03 version, which G++ also accepts but Clang and Comeau online
reject:

struct t { char c; };
struct f { char c[2]; };

template<int> struct Int { };

template<typename T>
struct has_static {
  template<typename X>
  static t check(X*, Int<sizeof(T::fun())>* = 0);
  static f check(...);

  static const bool value = sizeof(check((T*)(0))) == sizeof(t);
};

struct test { int fun() { return 0; } };

bool b = has_static<test>::value;

G++ does reject it for different invalid expressions, e.g. if fun doesn't exist
at all, so it does seem to be treating the decltype expression as outside the
immediate context during type deduction, but not consistently.


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
                   ` (2 preceding siblings ...)
  2012-06-28 10:36 ` redi at gcc dot gnu.org
@ 2012-06-28 17:37 ` exa7z at live dot com
  2012-06-28 17:43 ` exa7z at live dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: exa7z at live dot com @ 2012-06-28 17:37 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from exa7z at live dot com 2012-06-28 17:37:08 UTC ---
You are correct in noting that even in C++03 g++ behaves like this. I also
tried several other examples yesterday that led me to the same result. And I
think it is because of the way g++ behaves differently for what it concerns its
"vision" of dependent/non-dependent type names in this particular case.

The bug submission code was based on this:
========================================================
template<typename X>
static std::true_type check(X*, decltype(T::fun())* = 0);
========================================================

But it was supposed to be the following which compiles everywhere and is indeed
correct: (was worn out at the time and while testing I let a T in the place of
X by mistake):

========================================================
template<typename X>
static std::true_type check(X*, decltype(X::fun())* = 0);
========================================================

The difference is in using a non - dependent type name within check() for what
check() is concerned when T is used in decltype(T::fun()) while the corrected
version with X uses a dependent type name in decltype(X::fun()) for what
check() is concerned.

When check() gets to instantiation, T has already been substituted  before X
due to it being the dependent type name in has_static<...> and thus the non -
dependent name in check().

As such, a compiler will first have to decide whether the type name involved is
dependent or not, and since T is the non - dependent type for what check() is
concerned. Now, since the static ::fun() is not a valid test{} member, we are
trying to feed to decltype an unresolved symbol related to the *non-dependent*
type name for what check() is concerned.

Therefore, SFINAE cannot even take place because of that, T is the anchor
keeping the ship from sailing *when* a compiler does *not* make a distinction
between dependent and non-dependent type names in this case.

As a note, I believe there is one more source of confusion due to the existance
of .fun() as a symbol. The fact that there is a non - static member fun() makes
so that the error message we get from the other compilers is that of saying to
us that practically we should have used decltype(T().fun()) since they see that
a .fun() (NOT ::fun()) exists and deduce that likely we erred in our call
syntax... And the dependent / non - dependent type name issue is ignored. Since
compilers can make this distinction I do not see why a dependent/non-dependent
type name error should not have been raised in this case by *all*.

In summary, I believe that g++ is most likely behaving the way it does because
it treats both X and T as dependent type names in check() despite they are not
(only X is the actual dependent type name for check()) thus allowing SFINAE to
take place (aka T is not an anchor anymore!).


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
                   ` (3 preceding siblings ...)
  2012-06-28 17:37 ` exa7z at live dot com
@ 2012-06-28 17:43 ` exa7z at live dot com
  2012-07-02 21:05 ` jason at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: exa7z at live dot com @ 2012-06-28 17:43 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from exa7z at live dot com 2012-06-28 17:42:48 UTC ---
> 
> Therefore, SFINAE cannot even take place because of that, T is the anchor
> keeping the ship from sailing *when* a compiler does *not* make a distinction
> between dependent and non-dependent type names in this case.
>

[edit]
Therefore, SFINAE cannot even take place because of that, T is the anchor
keeping the ship from sailing *when* a compiler *does* make a *correct*
distinction between dependent and non-dependent type names in this case.
[/edit]


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
                   ` (4 preceding siblings ...)
  2012-06-28 17:43 ` exa7z at live dot com
@ 2012-07-02 21:05 ` jason at gcc dot gnu.org
  2012-07-03  3:30 ` jason at gcc dot gnu.org
  2012-07-03  3:31 ` jason at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jason at gcc dot gnu.org @ 2012-07-02 21:05 UTC (permalink / raw)
  To: gcc-bugs

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

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |jason at gcc dot gnu.org
         AssignedTo|unassigned at gcc dot       |jason at gcc dot gnu.org
                   |gnu.org                     |


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
                   ` (5 preceding siblings ...)
  2012-07-02 21:05 ` jason at gcc dot gnu.org
@ 2012-07-03  3:30 ` jason at gcc dot gnu.org
  2012-07-03  3:31 ` jason at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jason at gcc dot gnu.org @ 2012-07-03  3:30 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Jason Merrill <jason at gcc dot gnu.org> 2012-07-03 03:30:15 UTC ---
Author: jason
Date: Tue Jul  3 03:30:09 2012
New Revision: 189188

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=189188
Log:
    PR c++/53788
    * pt.c (build_non_dependent_expr): Don't wrap a dummy object.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/decltype39.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/diagnostic/method1.C


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

* [Bug c++/53788] C++11 decltype sfinae static member function check (4.7.1)
  2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
                   ` (6 preceding siblings ...)
  2012-07-03  3:30 ` jason at gcc dot gnu.org
@ 2012-07-03  3:31 ` jason at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jason at gcc dot gnu.org @ 2012-07-03  3:31 UTC (permalink / raw)
  To: gcc-bugs

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

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|                            |FIXED
   Target Milestone|---                         |4.8.0

--- Comment #7 from Jason Merrill <jason at gcc dot gnu.org> 2012-07-03 03:31:18 UTC ---
Fixed for 4.8.


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

end of thread, other threads:[~2012-07-03  3:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-27 18:43 [Bug c++/53788] New: C++11 decltype sfinae static member function check (4.7.1) exa7z at live dot com
2012-06-27 22:30 ` [Bug c++/53788] " daniel.kruegler at googlemail dot com
2012-06-28  9:45 ` redi at gcc dot gnu.org
2012-06-28 10:36 ` redi at gcc dot gnu.org
2012-06-28 17:37 ` exa7z at live dot com
2012-06-28 17:43 ` exa7z at live dot com
2012-07-02 21:05 ` jason at gcc dot gnu.org
2012-07-03  3:30 ` jason at gcc dot gnu.org
2012-07-03  3:31 ` jason 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).