summaryrefslogtreecommitdiff
path: root/gcc/cp/except.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2006-05-19 03:01:14 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2006-05-19 03:01:14 +0000
commita4a591f9f768fb7cde4659c2b4cf09031cee5486 (patch)
treee4b7d562777fd7a64677150037b1ea3eaa0694ff /gcc/cp/except.c
parentdb95162716d043bafcad068a3e6dc2baf22905ee (diff)
downloadgcc-a4a591f9f768fb7cde4659c2b4cf09031cee5486.tar.gz
PR c++/27471
PR c++/27506 * typeck.c (decay_conversion): Convert bitfields to their declared types here. Improve documentation. Avoid use of cp_convert. (default_conversion): Make it static. Perform integral promotions before lvalue-to-rvalue, function-to-pointer, and array-to-pointer conversions. * init.c (build_init): Remove. (expand_default_init): Do not call rvalue. * call.c (null_ptr_cst_p): Robustify. (build_conditional_expr): Tidy. * except.c (build_throw): Do not perform lvalue-to-rvalue conversion on operand before initializing temporary. * tree.c (convert.h): Include it. (convert_bitfield_to_declared_type): Use convert_to_integer, not cp_convert. (rvalue): Don't convert bitfields to their declared type here. * cp-tree.h (build_init): Remove. (default_conversion): Likewise. * typeck2.c (build_m_component_ref): Do not perform lvalue-to-rvalue, function-to-pointer, or array-to-pointer conversions here. Correct error message. PR c++/27471 PR c++/27506 * g++.dg/conversion/bitfield5.C: New test. * g++.dg/conversion/bitfield6.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113902 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/except.c')
-rw-r--r--gcc/cp/except.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index d82c07ff329..efdbd91e857 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -638,6 +638,7 @@ build_throw (tree exp)
else if (exp)
{
tree throw_type;
+ tree temp_type;
tree cleanup;
tree object, ptr;
tree tmp;
@@ -666,9 +667,17 @@ build_throw (tree exp)
fn = push_throw_library_fn (fn, tmp);
}
- /* throw expression */
- /* First, decay it. */
- exp = decay_conversion (exp);
+ /* [except.throw]
+
+ A throw-expression initializes a temporary object, the type
+ of which is determined by removing any top-level
+ cv-qualifiers from the static type of the operand of throw
+ and adjusting the type from "array of T" or "function return
+ T" to "pointer to T" or "pointer to function returning T"
+ respectively. */
+ temp_type = is_bitfield_expr_with_lowered_type (exp);
+ if (!temp_type)
+ temp_type = type_decays_to (TYPE_MAIN_VARIANT (TREE_TYPE (exp)));
/* OK, this is kind of wacky. The standard says that we call
terminate when the exception handling mechanism, after
@@ -684,21 +693,32 @@ build_throw (tree exp)
matter, since it can't throw). */
/* Allocate the space for the exception. */
- allocate_expr = do_allocate_exception (TREE_TYPE (exp));
+ allocate_expr = do_allocate_exception (temp_type);
allocate_expr = get_target_expr (allocate_expr);
ptr = TARGET_EXPR_SLOT (allocate_expr);
- object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
+ object = build_nop (build_pointer_type (temp_type), ptr);
object = build_indirect_ref (object, NULL);
elided = (TREE_CODE (exp) == TARGET_EXPR);
/* And initialize the exception object. */
- exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
- if (exp == error_mark_node)
+ if (CLASS_TYPE_P (temp_type))
{
- error (" in thrown expression");
- return error_mark_node;
+ /* Call the copy constructor. */
+ exp = (build_special_member_call
+ (object, complete_ctor_identifier,
+ build_tree_list (NULL_TREE, exp),
+ TREE_TYPE (object),
+ LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING));
+ if (exp == error_mark_node)
+ {
+ error (" in thrown expression");
+ return error_mark_node;
+ }
}
+ else
+ exp = build2 (INIT_EXPR, temp_type, object,
+ decay_conversion (exp));
/* Pre-evaluate the thrown expression first, since if we allocated
the space first we would have to deal with cleaning it up if