public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/57239] New: GCC cannot handle inner/nested class templates with non-type parameter packs that were declared in the outer/containing class
@ 2013-05-10 15:53 scottbaldwin at gmail dot com
  2013-05-11 13:14 ` [Bug c++/57239] " daniel.kruegler at googlemail dot com
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: scottbaldwin at gmail dot com @ 2013-05-10 15:53 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 57239
           Summary: GCC cannot handle inner/nested class templates with
                    non-type parameter packs that were declared in the
                    outer/containing class
           Product: gcc
           Version: 4.8.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: scottbaldwin at gmail dot com

GCC 4.7.2 and 4.8.x cannot handle inner/nested class templates with non-type
parameter packs that were declared in the outer/containing class's template
parameter list. This bug can result in either an "internal compile error", or
even generate incorrect code (both are demonstrated), which is why I marked
this bug as "major".

I encountered this bug while trying to implement a helper template called
is_instantiation_of__nontypes<> which is a non-type-parameter counterpart to
the is_instantiation_of<> template described at
[http://stackoverflow.com/questions/11251376/].

The demos below (one for compile-time error demo, one for run-time error demo)
are implementations of this is_instantiation_of__nontypes<> template and work
fine in clang, but in gcc 4.7.2 and 4.8.x fail to compile or produce incorrect
results. These demos should compile "out of the box" as they have no
dependencies other than the standard libraries.

----------------------------------------
compile-time error demo
----------------------------------------

    // generic version of is_instantiation_of__nontypes<> (the template to
check against is template-template parameter 'TT', taking "values" of the
non-type parameter pack 'Ts...' declared in outer/containing class)

    template<bool BoolVal, char CharVal>
    struct Foo {};

    template<typename... Ts>
    struct is_instantiation_of__nontypes
    {
        template<template<Ts...> class TT, typename T>
        struct check : std::false_type {};

        template<template<Ts...> class TT, Ts... Args>
        struct check<TT, TT<Args...>> : std::true_type {};
    };

    int main() {
        using FooInstantiation = Foo<false, 'x'>;
        std::cout << ((is_instantiation_of__nontypes<bool, char>::check<Foo,
FooInstantiation>::value) ? "yes" : "no") << endl;
    }
---
This fails to compile in gcc 4.7.2/4.8.x with the following errors:

[gcc 4.7.2]:
    make[1]: compiling [sandbox_cpp11.cpp] (gcc 4.7.2)
    sandbox_cpp11.cpp: In function ‘void gcc_bug_demo_3::_go_()’:
    sandbox_cpp11.cpp:122:88: error: type/value mismatch at argument 1 in
template parameter list for ‘template<class ... Ts>
template<template<template<Ts ...<anonymous> > class TT, class T>
template<class ... Ts> template<Ts ...<anonymous> > class TT, class T> struct
gcc_bug_demo_3::is_instantiation_of__nontypes<Ts>::check’
    sandbox_cpp11.cpp:122:88: error:   expected a template of type
‘template<class ... Ts> template<Ts ...<anonymous> > class TT’, got
‘template<bool BoolVal, char CharVal> struct gcc_bug_demo_3::Foo’
    make[1]: *** [dbg-mt/sandbox_cpp11.o] Error 1
    make: *** [objs] Error 2

[gcc 4.8.x]:
    make[1]: compiling [sandbox_cpp11.cpp] (gcc 4.8.x)
    sandbox_cpp11.cpp:116:27: error: ‘Ts ...’ is not a valid type for a
template non-type parameter
       struct check<TT, TT<Args...>> : std::true_type {};
                               ^
    sandbox_cpp11.cpp:116:30: error: template argument 2 is invalid
       struct check<TT, TT<Args...>> : std::true_type {};
                                  ^
    sandbox_cpp11.cpp: In function ‘void gcc_bug_demo_3::_go_()’:
    sandbox_cpp11.cpp:122:88: error: type/value mismatch at argument 1 in
template parameter list for ‘template<class ... Ts>
template<template<template<Ts ...<anonymous> > class TT, class T>
template<class ... Ts> template<Ts ...<anonymous> > class TT, class T> struct
gcc_bug_demo_3::is_instantiation_of__nontypes<Ts>::check’
       std::cout << ((is_instantiation_of__nontypes<bool, char>::check<Foo,
FooInstantiation>::value) ? "yes" : "no") << endl;
                                                                               
        ^
    sandbox_cpp11.cpp:122:88: error:   expected a template of type
‘template<class ... Ts> template<Ts ...<anonymous> > class TT’, got
‘template<bool BoolVal, char CharVal> struct gcc_bug_demo_3::Foo’
    make[1]: *** [dbg-mt/sandbox_cpp11.o] Error 1
    make: *** [objs] Error 2

4.8.x is slightly more verbose with the additional "error: ‘Ts ...’ is not a
valid type for a template non-type parameter", which is incorrect since 'Ts...'
was properly declared as a parameter pack in the containing class's template
parameter list.
In fact, if you simplify the code (by removing template-template parameter 'TT'
and replacing it w/ hard-coded template class 'Foo') then it compiles fine, but
has incorrect results at runtime, as demonstrated in the following code ...

----------------------------------------
run-time error demo
----------------------------------------

    // simplified version of is_instantiation_of__nontypes<> (the template to
check against is hardcoded as template 'Foo', instead of being
template-template parameter 'TT')
    // compiles without error in all 4 compilers tested (gcc 4.7.2, 4.8.0,
4.8.1, and clang 3.3), but only has correct runtime results (output of "yes")
when compiled with clang.

    template<bool BoolVal, char CharVal>
    struct Foo {};

    template<typename... Ts>
    struct is_instantiation_of__nontypes // hard-coded for class template Foo
    {
        template<typename T>
        struct check : std::false_type {};

        template<Ts... Args>
        struct check<Foo<Args...>> : std::true_type {};
    };

    int main() {
        using FooInstantiation = Foo<false, 'x'>;
        // the next line will output "yes" if the compiler has correct logic,
or "no" otherwise
        std::cout << ((is_instantiation_of__nontypes<bool,
char>::check<FooInstantiation>::value) ? "yes" : "no") << std::endl;
    }

This demo outputs "yes" when compiled with clang (3.3), but outputs "no" when
compiled with gcc (4.7.2 or 4.8.x).
>From gcc-bugs-return-422035-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Fri May 10 16:05:46 2013
Return-Path: <gcc-bugs-return-422035-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 13499 invoked by alias); 10 May 2013 16:05:46 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 13451 invoked by uid 48); 10 May 2013 16:05:41 -0000
From: "paolo.carlini at oracle dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/57239] GCC cannot handle inner/nested class templates with non-type parameter packs that were declared in the outer/containing class
Date: Fri, 10 May 2013 16:05:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: c++
X-Bugzilla-Version: 4.8.1
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: paolo.carlini at oracle dot com
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_severity
Message-ID: <bug-57239-4-DA6ov8LROt@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-57239-4@http.gcc.gnu.org/bugzilla/>
References: <bug-57239-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2013-05/txt/msg00708.txt.bz2
Content-length: 298

http://gcc.gnu.org/bugzilla/show_bug.cgi?idW239

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|major                       |normal


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

end of thread, other threads:[~2021-12-03  3:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-10 15:53 [Bug c++/57239] New: GCC cannot handle inner/nested class templates with non-type parameter packs that were declared in the outer/containing class scottbaldwin at gmail dot com
2013-05-11 13:14 ` [Bug c++/57239] " daniel.kruegler at googlemail dot com
2013-06-26  9:53 ` scottbaldwin at gmail dot com
2013-06-26 10:16 ` redi at gcc dot gnu.org
2013-06-26 10:29 ` redi at gcc dot gnu.org
2013-06-26 10:55 ` scottbaldwin at gmail dot com
2013-06-26 11:32 ` redi at gcc dot gnu.org
2013-06-26 12:08 ` scottbaldwin at gmail dot com
2013-06-26 14:23 ` scottbaldwin at gmail dot com
2013-06-26 15:23 ` redi at gcc dot gnu.org
2013-06-26 16:04 ` scottbaldwin at gmail dot com
2013-06-26 17:56 ` paolo.carlini at oracle dot com
2021-12-03  3:45 ` pinskia 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).