aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGabriel Dos Reis <gdr@codesourcery.com>2001-03-15 07:59:53 +0000
committerGabriel Dos Reis <gdr@gcc.gnu.org>2001-03-15 07:59:53 +0000
commitd064d75a33a6a4bea4d8a863ddff6bc88281029d (patch)
tree26a5e318a3736edd7e0207acd62e762714ec16e9 /gcc
parentba133c968c260e4f4c9623630812846202b5e54f (diff)
downloadgcc-d064d75a33a6a4bea4d8a863ddff6bc88281029d.zip
gcc-d064d75a33a6a4bea4d8a863ddff6bc88281029d.tar.gz
gcc-d064d75a33a6a4bea4d8a863ddff6bc88281029d.tar.bz2
Correct semantics restrictions checking in throw-expression.
cp/ Correct semantics restrictions checking in throw-expression. * except.c (is_admissible_throw_operand): New function. (build_throw): Use it. testsuite/ * g++.old-deja/g++.other/eh4.C: New test. From-SVN: r40487
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/except.c35
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/eh4.C12
4 files changed, 56 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4258b7e..429a570 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2001-03-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ Correct semantics restrictions checking in throw-expression.
+ * except.c (is_admissible_throw_operand): New function.
+ (build_throw): Use it.
+
2001-03-14 Mark Mitchell <mark@codesourcery.com>
* decl.c (cp_make_fnname_decl): Set DECL_IGNORED_P on __FUNCTION__
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index fbfb709..595d3d6 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -53,6 +53,7 @@ static tree build_eh_type_type_ref PARAMS ((tree));
static tree build_terminate_handler PARAMS ((void));
static tree alloc_eh_object PARAMS ((tree));
static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
+static bool is_admissible_throw_operand PARAMS ((tree));
static int can_convert_eh PARAMS ((tree, tree));
static void check_handlers_1 PARAMS ((tree, tree));
static void initialize_handler_parm PARAMS ((tree));
@@ -1027,7 +1028,7 @@ build_throw (e)
if (e != NULL_TREE)
{
- if (!complete_ptr_ref_or_void_ptr_p (TREE_TYPE (e), e))
+ if (!is_admissible_throw_operand (e))
return error_mark_node;
}
@@ -1070,6 +1071,38 @@ complete_ptr_ref_or_void_ptr_p (type, from)
return 1;
}
+/* Return truth-value if EXPRESSION is admissible in throw-expression,
+ i.e. if it is not of incomplete type or a pointer/reference to such
+ a type or of an abstract class type. */
+
+static bool
+is_admissible_throw_operand (expr)
+ tree expr;
+{
+ tree type = TREE_TYPE (expr);
+
+ /* 15.1/4 [...] The type of the throw-expression shall not be an
+ incomplete type, or a pointer or a reference to an incomplete
+ type, other than void*, const void*, volatile void*, or
+ const volatile void*. Except for these restriction and the
+ restrictions on type matching mentioned in 15.3, the operand
+ of throw is treated exactly as a function argument in a call
+ (5.2.2) or the operand of a return statement. */
+ if (!complete_ptr_ref_or_void_ptr_p (type, expr))
+ return false;
+
+ /* 10.4/3 An abstract class shall not be used as a parameter type,
+ as a function return type or as type of an explicit
+ conversion. */
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
+ {
+ cp_error ("Expression '%E' of abstract class type '%T' cannot be used in throw-expression", expr, type);
+ return false;
+ }
+
+ return true;
+}
+
/* Returns nonzero if FN is a declaration of a standard C library
function which is known not to throw.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 163ef96..12bb57f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2001-03-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * g++.old-deja/g++.other/eh4.C: New test.
+
2001-03-14 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/mi1.c: Update.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/eh4.C b/gcc/testsuite/g++.old-deja/g++.other/eh4.C
new file mode 100644
index 0000000..437d9a7
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/eh4.C
@@ -0,0 +1,12 @@
+// Origin: Jean-Marc Bourguet <bourguet@cadence.com>
+// Build, don't link:
+
+class foo {
+public:
+ foo() {};
+ void throwMe () {
+ throw *this; // ERROR
+ };
+ virtual void test () = 0;
+};
+