Bug 56323 - [C++11] cannot compile inherited constructor for typedef'ed base class
Summary: [C++11] cannot compile inherited constructor for typedef'ed base class
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: 4.8.0
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
: 56333 (view as bug list)
Depends on:
Blocks:
 
Reported: 2013-02-14 14:33 UTC by Takaki Makino
Modified: 2013-02-27 18:13 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-02-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Takaki Makino 2013-02-14 14:33:51 UTC
Consider the following code that uses inherited constructor from a typedef'ed type:

------------------------
struct A {
        A(int i);
};

typedef A B;

struct C : B {
        using B::B; // compile error by gcc
};

struct D : B {
        using B::A; // this is compiled as inherited constructor
};

C c(0);
D d(0);
------------------------

I believe that C should be valid, while D should be reported as invalid.  However I cannot find anything about this problem in the C++11 standard...

In template programming, using inherited constructor is sometimes virtually impossible, as in the following example.

------------------------
struct A {
        A(int i);
};

template <class T>
struct E {
        typedef T type;
};

template <class T>
struct F : E<T>::type {
        using E<T>::type::type; // error: E<T>::type is a typedef
};

F<A> f(0);
------------------------
Comment 1 Jonathan Wakely 2013-02-14 14:42:20 UTC
I think [class.qual]/2 says both C and D are valid.

C is valid because it is a using-declaration that is a member-declaration and the name specified after the nested-name-specifier is the same as the identifier in the last component of the nested-name-specifier.

D is valid because the name specified after the nested-name-specifier is the injected-class-name of A.

In both cases the using-declaration names the constructor, so it declares a set of inheriting constructors.
Comment 2 Jason Merrill 2013-02-15 01:27:09 UTC
Author: jason
Date: Fri Feb 15 01:27:03 2013
New Revision: 196067

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196067
Log:
	PR c++/56323
	* name-lookup.c (do_class_using_decl): Handle typedefs with
	inheriting constructors.
	(push_class_level_binding_1): Allow inheriting from template
	template parameter, too.
	* pt.c (tsubst_decl) [USING_DECL]: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/inh-ctor17.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/cp/pt.c
Comment 3 Jonathan Wakely 2013-02-15 09:10:28 UTC
*** Bug 56333 has been marked as a duplicate of this bug. ***
Comment 4 Paolo Carlini 2013-02-15 11:17:07 UTC
Fixed.
Comment 5 Jason Merrill 2013-02-27 18:13:34 UTC
Author: jason
Date: Wed Feb 27 18:13:24 2013
New Revision: 196316

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196316
Log:
	PR c++/56358
	PR c++/56323
	* name-lookup.c (do_class_using_decl): Use ctor_identifier instead
	of the base name for inheriting ctors.
	(push_class_level_binding_1): Remove inheriting ctor handling.
	* pt.c (tsubst_decl) [USING_DECL]: Likewise.
	* class.c (add_implicitly_declared_members): Adjust.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/inh-ctor18.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/class.c
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/g++.dg/inherit/using5.C
    trunk/gcc/testsuite/g++.old-deja/g++.other/using3.C