Commit e350dbbd by Paolo Bonzini Committed by Paolo Bonzini

re PR c++/36897 (ICE with function pointer template parameter)

gcc/cp:
2009-02-03  Paolo Bonzini  <bonzini@gnu.org>

	PR c++/36897
	* pt.c (convert_nontype_argument_function): Expect expr to be an
	ADDR_EXPR.

	PR c++/37314
	* typeck.c (merge_types): Call resolve_typename_type if only
	one type is a typename.

gcc/testsuite:
2009-02-03  Paolo Bonzini  <bonzini@gnu.org>

	PR c++/36897
	* g++.dg/template/func2.C: New test.

	PR c++/37314
	* g++.dg/template/typename15.C: New.
	* g++.dg/template/typename16.C: New.

From-SVN: r143898
parent aa2bb640
2009-02-03 Paolo Bonzini <bonzini@gnu.org>
PR c++/36897
* pt.c (convert_nontype_argument_function): Expect expr to be an
ADDR_EXPR.
PR c++/37314
* typeck.c (merge_types): Call resolve_typename_type if only
one type is a typename.
2009-02-02 Jason Merrill <jason@redhat.com>
PR c++/39054
......
......@@ -4566,6 +4566,13 @@ convert_nontype_argument (tree type, tree expr)
expr = convert_nontype_argument_function (type, expr);
if (!expr || expr == error_mark_node)
return expr;
if (TREE_CODE (expr) != ADDR_EXPR)
{
error ("%qE is not a valid template argument for type %qT", expr, type);
error ("it must be the address of a function with external linkage");
return NULL_TREE;
}
}
/* [temp.arg.nontype]/5, bullet 5
......
......@@ -637,6 +637,20 @@ merge_types (tree t1, tree t2)
code1 = TREE_CODE (t1);
code2 = TREE_CODE (t2);
if (code1 != code2)
{
gcc_assert (code1 == TYPENAME_TYPE || code2 == TYPENAME_TYPE);
if (code1 == TYPENAME_TYPE)
{
t1 = resolve_typename_type (t1, /*only_current_p=*/true);
code1 = TREE_CODE (t1);
}
else
{
t2 = resolve_typename_type (t2, /*only_current_p=*/true);
code2 = TREE_CODE (t2);
}
}
switch (code1)
{
......
2009-02-03 Paolo Bonzini <bonzini@gnu.org>
PR c++/36897
* g++.dg/template/func2.C: New test.
PR c++/37314
* g++.dg/template/typename15.C: New.
* g++.dg/template/typename16.C: New.
2009-02-03 Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>
......
// { dg-do compile }
typedef void (*fptr)();
fptr zeroptr = 0;
template<typename T, fptr F> struct foo { };
template<typename T> struct foo<T,zeroptr> { };
// { dg-error "not a valid template argument" "not valid" { target *-*-* } 6 }
// { dg-error "must be the address" "must be the address " { target *-*-* } 6 }
// The rest is needed to trigger the ICE in 4.0 to 4.3:
void f() { }
foo<int,&f> m_foo;
// PR37314 ice-on-valid-code, from w.doeringer
template <typename T>
class Cdeque {
typedef T *pointer;
class iterator {
typedef typename Cdeque<T>::pointer pointer;
pointer operator->();
};
};
template <typename T> T* Cdeque<T>::iterator::operator->() { }
// PR37314 rejects-valid, from w.doeringer
template <typename T>
struct A {
typedef __PTRDIFF_TYPE__ difference_type;
struct B {
typedef typename A<T>::difference_type difference_type;
difference_type operator-(B const&) const;
T t;
};
};
//
template <typename T>
typename A<T>::B::difference_type A<T>::B::operator-(B const&) const {
return -1;
}
//
int main() {
A<int>::B i;
++i.t;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment