Bug 39413 - static_assert and SFINAE
Summary: static_assert and SFINAE
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: 4.5.0
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2009-03-09 17:19 UTC by Piotr Wyderski
Modified: 2009-11-04 22:31 UTC (History)
2 users (show)

See Also:
Host: GCC-4.4.0 (20090309), Cygwin, Windows XP
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-11-04 21:27:44


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Piotr Wyderski 2009-03-09 17:19:53 UTC
G++ fails when compiling the following program in
g++0x mode. It displays "spooky action at a distance"
when instantiating the member_ptr template, but I
expect the converting assignment operator from weak_ptr
to be selected instead.

-------------------------8<-----------------------


#include <type_traits>

    class A {

    };

    class B : public A {

    };

    class C {

    };


    namespace gc {

        template <typename T> class member_ptr;
    }


    template <typename T> class weak_ptr {

    public:

        weak_ptr() {}

        template <typename X> weak_ptr(const weak_ptr<X>& v) {}

        weak_ptr(const weak_ptr&) = default;

        weak_ptr(const gc::member_ptr<T>& v);

        ~weak_ptr() = default;

        // ------------------

        weak_ptr& operator =(const weak_ptr&) = default;

        template <typename X> weak_ptr& operator =(const weak_ptr<X>& v) { return *this; }
    };

    namespace gc {

        template <typename T> class member_ptr {

            static_assert(std::is_base_of<C, T>::value,
              "spooky action at a distance");
        };
    }



int main(int argc, char *argv[]) {

    weak_ptr<A> ap1;
    weak_ptr<B> bp1;

    ap1 = bp1;

    return 0;
}


-------------------------8<-----------------------
Comment 1 Paolo Carlini 2009-03-09 17:48:22 UTC
let's try to simplify the issue as much as possible... are defaulted / deleted functions really necessary to trigger the bug? Thus, is c++0x mode really necessary?
Comment 2 Paolo Carlini 2009-03-09 18:10:02 UTC
The below, not using any header neither C++0x mode (very likely can be further reduced), doesn't compile with mainline and 4_3-branch, does with EDG-based compilers in strict mode:

template<bool>
  class __static_assert { };

template<>
  class __static_assert<false>;

template<typename T, typename U>
  struct __are_same { static const bool value = false; };

template<typename T>
  struct __are_same<T, T> { static const bool value = true; };

    class A {

    };

    class B : public A {

    };

    class C {

    };

    namespace gc {

        template <typename T> class member_ptr;
    }

    template <typename T> class weak_ptr {

    public:

        weak_ptr() {}

        template <typename X> weak_ptr(const weak_ptr<X>& v) {}

        weak_ptr(const gc::member_ptr<T>& v);

        template <typename X> weak_ptr& operator=(const weak_ptr<X>& v) { return *this; }
    };

    namespace gc {

        template <typename T> class member_ptr {

	  __static_assert<__are_same<C, T>::value> sa;
       };
    }

int main() {

    weak_ptr<A> ap1;
    weak_ptr<B> bp1;

    ap1 = bp1;
}


Comment 3 Paolo Carlini 2009-03-09 18:17:53 UTC
Volunteers for a better Summary?
Comment 4 Paolo Carlini 2009-03-17 12:55:07 UTC
Jason, are you willing to help triaging this one?
Comment 5 Paolo Carlini 2009-03-17 12:55:43 UTC
Sorry, CC-ed Jakub instead of Jason ;)
Comment 6 Jason Merrill 2009-11-04 21:27:44 UTC
This is not a SFINAE issue, the bug is that we shouldn't be instantiating member_ptr in the first place in order to resolve the operator= overload.
Comment 7 Jason Merrill 2009-11-04 22:29:48 UTC
Subject: Bug 39413

Author: jason
Date: Wed Nov  4 22:29:35 2009
New Revision: 153920

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153920
Log:
	PR c++/39413
	* search.c (lookup_base): Don't complete_type (base).

Added:
    trunk/gcc/testsuite/g++.dg/template/overload11.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/search.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/template/nested3.C

Comment 8 Jason Merrill 2009-11-04 22:31:00 UTC
Fixed for 4.5.0.