From: Nathan Sidwell Date: Fri, 4 Jun 1999 01:31:42 +0000 (+0000) Subject: * except.c (build_throw): Check throw expression validity. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=980c394cc794bc96e13ebcaa756573f3bd729681;p=gcc.git * except.c (build_throw): Check throw expression validity. From-SVN: r27344 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b7f428906ab..d59db6bf0fa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +1999-06-04 Nathan Sidwell + + * except.c (build_throw): Check throw expression validity. + 1999-06-03 Mark Mitchell * decl.c (grokdeclarator): Don't treat arbitrary types as unsigned diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 9e2d6af592a..5bdbd8c979b 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -1152,6 +1152,30 @@ build_throw (e) if (e == null_node) cp_warning ("throwing NULL, which has integral, not pointer type"); + + if (e != NULL_TREE) + { + tree core; + int is_ptr; + + /* Cannot throw an incomplete type. */ + e = require_complete_type (e); + if (e == error_mark_node) + return e; + + /* Or a pointer or ref to one, other than cv void *. */ + core = TREE_TYPE (e); + is_ptr = TREE_CODE (core) == POINTER_TYPE; + if (is_ptr || TREE_CODE (core) == REFERENCE_TYPE) + { + core = TREE_TYPE (core); + + if (is_ptr && same_type_p (TYPE_MAIN_VARIANT (core), void_type_node)) + /* OK */; + else if (!complete_type_or_else (core, NULL_TREE)) + return error_mark_node; + } + } e = build1 (THROW_EXPR, void_type_node, e); TREE_SIDE_EFFECTS (e) = 1; diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eh990323-1.C b/gcc/testsuite/g++.old-deja/g++.robertl/eh990323-1.C index 9bf8a098c0f..ef6d2dc77e1 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eh990323-1.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eh990323-1.C @@ -17,7 +17,7 @@ template void ff(T) { } -void g(void) +void g(int) { } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-1.C b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-1.C index c03154bdf8a..06112d257c5 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-1.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-1.C @@ -1,7 +1,9 @@ +// Build don't link: + //test 2 struct A {}; void f() { - struct A; - throw *(new A); + struct A; // ERROR - forward ref + throw *(new A); // ERROR - invalid use of undefined type } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-2.C b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-2.C index 3fa5bd566d1..0686ee5748d 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-2.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-2.C @@ -25,7 +25,7 @@ void f4() throw A > ("hi michey"); } -main() +int main() { int flag; diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-3.C b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-3.C index 55cb16c705e..842e6478f5b 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-3.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-3.C @@ -1,3 +1,4 @@ +// Build don't link: // try throwing overloaded function void f(int) @@ -10,5 +11,5 @@ void f(long) void g() { - throw &f; + throw &f; // ERROR - insufficient contextual information } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-4.C b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-4.C index 85bbb457d34..7f3f20ef92d 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-4.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-4.C @@ -1,3 +1,4 @@ +// Build don't link: // try throwing template function name template void f(T); @@ -8,5 +9,5 @@ template void f(T) void g() { - throw &f; + throw &f; // ERROR - insufficient contextual information } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-5.C b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-5.C index c49b66e9fa5..45225e3f0ce 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-5.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/ice990323-5.C @@ -1,3 +1,4 @@ +// Build don't link: // check attempting to throw an overloaded function struct A { @@ -7,5 +8,5 @@ struct A { void g() { - throw &A::f; + throw &A::f; // ERROR - insufficient context }