This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 27801, 26496, 27385
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 31 May 2006 13:11:37 -0700
- Subject: C++ PATCH: PR 27801, 26496, 27385
- Reply-to: mark at codesourcery dot com
This patch fixes three of Volker's many ICEs.
PR 27801 was a crash in fold, when processing a non-dependent
expression in a template. We called fold as part of processing a
conversion -- but there's no real reason to actually perform
conversions while processing a template, since all we need to know is
that the conversion worked.
PR 26496 was a crash on an invalid use of a non-static member
function. We already warn about many of the invalid uses; this was
one more.
PR 27385 was an infinite loop on an ill-formed initializer. Here, we
reported an error, but failed to propagate the error_mark_node.
Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
4.1 branch.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-05-31 Mark Mitchell <mark@codesourcery.com>
PR c++/27801
* call.c (perform_implicit_conversion): Do not actually perform
conversions in templates.
PR c++/26496
* call.c (resolve_args): Check for invalid uses of bound
non-static member functions.
* init.c (build_offset_ref): Return error_mark_node for errors.
PR c++/27385
* decl.c (reshape_init): Robustify.
(reshape_init_array_1): Likewise.
2006-05-31 Mark Mitchell <mark@codesourcery.com>
PR c++/27801
* g++.dg/template/cond6.C: New test.
PR c++/26496
* g++.dg/template/crash51.C: New test.
* g++.old-deja/g++.mike/net36.C: Tweak error markers.
PR c++/27385
* g++.dg/init/array20.C: New test.
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c (revision 114244)
+++ gcc/cp/init.c (working copy)
@@ -1426,7 +1426,7 @@ build_offset_ref (tree type, tree member
}
error ("invalid use of non-static member function %qD",
TREE_OPERAND (member, 1));
- return member;
+ return error_mark_node;
}
else if (TREE_CODE (member) == FIELD_DECL)
{
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 114244)
+++ gcc/cp/decl.c (working copy)
@@ -4352,6 +4352,8 @@ reshape_init_array_1 (tree elt_type, tre
}
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
+ if (elt_init == error_mark_node)
+ return error_mark_node;
CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
}
@@ -4630,6 +4632,8 @@ reshape_init (tree type, tree init)
d.end = d.cur + VEC_length (constructor_elt, v);
new_init = reshape_init_r (type, &d, true);
+ if (new_init == error_mark_node)
+ return error_mark_node;
/* Make sure all the element of the constructor were used. Otherwise,
issue an error about exceeding initializers. */
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c (revision 114244)
+++ gcc/cp/call.c (working copy)
@@ -2704,6 +2704,8 @@ resolve_args (tree args)
error ("invalid use of void expression");
return error_mark_node;
}
+ else if (invalid_nonstatic_memfn_p (arg))
+ return error_mark_node;
}
return args;
}
@@ -6388,6 +6390,14 @@ perform_implicit_conversion (tree type,
error ("could not convert %qE to %qT", expr, type);
expr = error_mark_node;
}
+ else if (processing_template_decl)
+ {
+ /* In a template, we are only concerned about determining the
+ type of non-dependent expressions, so we do not have to
+ perform the actual conversion. */
+ if (TREE_TYPE (expr) != type)
+ expr = build_nop (type, expr);
+ }
else
expr = convert_like (conv, expr);
Index: gcc/testsuite/g++.old-deja/g++.mike/net36.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/net36.C (revision 114207)
+++ gcc/testsuite/g++.old-deja/g++.mike/net36.C (working copy)
@@ -11,7 +11,7 @@ typedef void (A::*handler) (X*);
class B {
public:
- void setHandler(handler); // { dg-error "candidate" }
+ void setHandler(handler);
};
void f(B* b) {
Index: gcc/testsuite/g++.dg/init/array20.C
===================================================================
--- gcc/testsuite/g++.dg/init/array20.C (revision 0)
+++ gcc/testsuite/g++.dg/init/array20.C (revision 0)
@@ -0,0 +1,5 @@
+// PR c++/27385
+
+struct A {};
+A a[] = { 0 }; // { dg-error "initializer" }
+
Index: gcc/testsuite/g++.dg/template/crash51.C
===================================================================
--- gcc/testsuite/g++.dg/template/crash51.C (revision 0)
+++ gcc/testsuite/g++.dg/template/crash51.C (revision 0)
@@ -0,0 +1,11 @@
+// PR c++/26496
+
+template< typename _Generator> int generate_n(_Generator __gen);
+struct Distribution { };
+typedef double (Distribution::* Pstd_mem)();
+int main(void)
+{
+ Distribution* rng;
+ Pstd_mem ptr;
+ generate_n(rng->*ptr); // { dg-error "non-static member" }
+}
Index: gcc/testsuite/g++.dg/template/cond6.C
===================================================================
--- gcc/testsuite/g++.dg/template/cond6.C (revision 0)
+++ gcc/testsuite/g++.dg/template/cond6.C (revision 0)
@@ -0,0 +1,6 @@
+// PR c++/27801
+
+template<int> int foo(int i)
+{
+ return !( (1 && i) ? 0 : 1 );
+}