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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143898
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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
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>
--- /dev/null
+// { 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;
--- /dev/null
+// 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->() { }
+
+
--- /dev/null
+// 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;
+}
+
+