Bug 34219 - [C++0x] gcc doesn't accept const members of variadic templates as const (regression)
Summary: [C++0x] gcc doesn't accept const members of variadic templates as const (regr...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: error-recovery, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2007-11-25 00:11 UTC by René Bürgel
Modified: 2009-10-07 19:50 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.3.0
Last reconfirmed: 2007-12-20 21:07:30


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description René Bürgel 2007-11-25 00:11:35 UTC
template<typename T, T a, T... Params>
struct max
{
	static const T value = a > max<T, Params>::value ? a : max<T, Params>::value;
};

template<typename T, T a, T b>
struct max<T, a, b>
{
	static const T value = a > b ? a : b;
};

static const int value1 = max< int, 1, 2>::value;
static const int value2 = max< int, 1, 3, 5>::value;



As the initialization for value1 is accepted as valid, that should be also the case for value2. But g++ fails with the following error:

g++-4.3.0 -std=c++0x    -c -o test.o test.cpp
test.cpp: In instantiation of 'const int max<int, 1, 3, 5>::value':
test.cpp:14:   instantiated from here
test.cpp:4: error: 'max<int, 1, 3, 5>::value' cannot be initialized by a non-constant expression when being declared


g++ Version is "gcc version 4.3.0 20071123 (experimental) (GCC)"
Comment 1 Paolo Carlini 2007-11-25 01:01:15 UTC
Doug, can you have a look? Adding the missing definitions moves the error to link-time but it persists: something seems indeed fishy in the front-end code for static constant members vs variadic templates...
Comment 2 Andrew Pinski 2007-11-25 03:15:38 UTC
value = MAX_EXPR <(int) value, 1>


Which means we did not "inline" the value of the other value.

Confirmed.
Comment 3 René Bürgel 2008-01-19 22:38:23 UTC
another testcase:

template<template<typename... T> class Comp, typename... T> void f( T... Value)
{
  static_assert( Comp<T>::value > 0, "" );
}

template <typename... T>
struct Foo
{
	static const int value=1;
};

int main()
{
	f<Foo>( 2 );
}
Comment 4 dgregor 2008-01-28 23:40:34 UTC
There are some problems with the example code. For example, the expression max<T, Params> does not expand the parameter pack "Params". The compiler should have warned you about this, both in this case and in the static_assert case.
Comment 5 René Bürgel 2008-01-29 10:17:33 UTC
for #3, using static_assert( Comp<T...>::value > 0, "" ); makes it work.

using max<T, Params...> for #1 leads gcc to an error: "cannot expand 'Params ...' into a fixed-length argument list"


updated testcase:

template<typename T, T a, T... Params>
struct max
{
	static const T value = a > max<T, Params...>::value ? a : max<T, Params...>::value;
};

template<typename T, T a, T b>
struct max<T, a, b>
{
	static const T value = a > b ? a : b;
};

static const int value1 = max< int, 1, 2>::value;
static const int value2 = max< int, 1, 3, 5>::value;

If there are no more errors in thats code, this is a rejects-valid, not an error-recovery
Comment 6 dgregor 2008-01-29 14:01:07 UTC
Subject: Bug 34219

Author: dgregor
Date: Tue Jan 29 13:59:59 2008
New Revision: 131938

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131938
Log:
2008-01-29  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/34055
	PR c++/34103
	PR c++/34219
	PR c++/34606
	PR c++/34753
	PR c++/34754
	PR c++/34755
	PR c++/34919
	PR c++/34961
	* c-pretty-print.c (pp_c_type_qualifier_list): Don't try to print
	qualifiers for an ERROR_MARK_NODE or a NULL_TREE.


2008-01-29  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/34055
	PR c++/34103
	PR c++/34219
	PR c++/34606
	PR c++/34753
	PR c++/34754
	PR c++/34755
	PR c++/34919
	PR c++/34961
	* typeck.c (check_return_expr): Tweak call to
	check_for_bare_parameter_packs.
	* class.c (add_method): Be careful with error_mark_nodes.
	* cp-tree.h (check_for_bare_parameter_packs): Remove "*" from
	signature.
	* pt.c (struct find_parameter_pack_data): Remove
	SET_PACKS_TO_ERROR.
	(find_parameter_packs_r): Don't use SET_PACKS_TO_ERROR.
	(uses_parameter_packs): Don't set SET_PACKS_TO_ERROR.
	(make_pack_expansion): Ditto.
	(check_for_bare_parameter_packs): Parameter is now a tree, not a
	tree*.
	(process_template_parm): Tweak call to
	check_for_bare_parameter_packs.  
	(push_template_decl_real): Tweak calls to
	check_for_bare_parameter_packs. If bare parameter packs are found
	in the list of exceptions, clear out that list after giving an
	error.
	* semantics.c (finish_cond): Tweak call to
	check_for_bare_parameter_packs.
	(finish_expr_stmt): Ditto.
	(finish_for_expr): Ditto.
	(finish_switch_cond): Ditto.
	(finish_mem_initializers): Ditto.
	(finish_member_declaration): Ditto.
	(finish_static_assert): Check for bare parameter packs in the
	condition.
	* decl2.c (cplus_decl_attributes): Check for bare parameter packs in the
	attributes of a declaration.
	* parser.c (cp_parser_using_declaration): Tweak call to
	check_for_bare_parameter_packs.
	(cp_parser_base_clause): Ditto.
	

2008-01-29  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/34055
	PR c++/34103
	PR c++/34219
	PR c++/34606
	PR c++/34753
	PR c++/34754
	PR c++/34755
	PR c++/34919
	PR c++/34961
	* g++.dg/cpp0x/vt-34219-2.C: New.
	* g++.dg/cpp0x/pr32126.C: Tweak expected error messages.
	* g++.dg/cpp0x/vt-34961.C: New.
	* g++.dg/cpp0x/vt-34055.C: Tweak error messages; add new test
	cases from the re-opened PR.
	* g++.dg/cpp0x/vt-34753.C: New.
	* g++.dg/cpp0x/vt-34919.C: New.
	* g++.dg/cpp0x/vt-34754.C: New.
	* g++.dg/cpp0x/vt-34606.C: New.
	* g++.dg/cpp0x/vt-34219.C: New.
	* g++.dg/cpp0x/pr32125.C: Tweak expected error messages.
	* g++.dg/cpp0x/vt-34755.C: New.
	* g++.dg/cpp0x/pr31438.C: Ditto.
	* g++.dg/cpp0x/variadic81.C: Ditto.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34219-2.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34219.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34606.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34753.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34754.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34755.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34919.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34961.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-pretty-print.c
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/class.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/pr31438.C
    trunk/gcc/testsuite/g++.dg/cpp0x/pr32125.C
    trunk/gcc/testsuite/g++.dg/cpp0x/pr32126.C
    trunk/gcc/testsuite/g++.dg/cpp0x/variadic81.C
    trunk/gcc/testsuite/g++.dg/cpp0x/vt-34055.C

Comment 7 dgregor 2008-01-29 14:22:53 UTC
Actually, I don't know whether max<T, Params...> is valid or not. My inclination is that it is invalid, because when Params is empty, it becomes an invalid specialization max<T>. (This happens, for example, if we try to compute max<int, 17>::value. However, it's not clear to me whether the wording in the C++0x working draft supports that view or not. We say this about function parameter pack arguments not matching to normal function parameters in partial ordering, but we don't talk about this case at all.

I am going to submit an issue to the C++ Core Working Group to get this clarified. Until then, I'm going to suspend this bug: then we'll either close it (if the committee deems this code ill-formed) or re-open it to be fixed in GCC 4.4.

Comment 8 dgregor 2008-01-29 14:24:58 UTC
Fixed on mainline
Comment 9 Jason Merrill 2009-10-07 19:50:43 UTC
This was fixed long ago.