This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ Patch] Avoid spurious libsupc++ warnings
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 27 Jul 2008 17:51:34 +0200
- Subject: Re: [C++ Patch] Avoid spurious libsupc++ warnings
- References: <4888BACE.1050001@oracle.com> <488A0525.2090902@codesourcery.com>
Hi,
... The straightforward patch, with a comment for the new variable, is
pre-approved after testing.
For bonus points, put a little declare_nothrow_library_fn function in
except.c with the comment about matching libsupc++. If you think
that's gratuitous overkill, leave that bit out.
The below is that patch I just commited, after regtesting on
x86_64-linux. Many thanks for the quick review!
Paolo.
///////////////////
2008-07-27 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (push_library_fn): Add a parameter for the exceptions that
the function may throw.
(push_void_library_fn, push_throw_library_fn, expand_static_init):
Adjust.
(build_library_fn): Change to static.
* cp-tree.h: Adjust declarations.
* except.c (declare_nothrow_library_fn): New.
(do_get_exception_ptr, do_begin_catch, do_free_exception,
do_allocate_exception): Use the latter, adjust the declarations
(ie, add empty exception-specification), consistently with the
actual implementation in libsupc++.
Index: decl.c
===================================================================
*** decl.c (revision 138187)
--- decl.c (working copy)
*************** build_library_fn_1 (tree name, enum tree
*** 3590,3596 ****
We assume that such functions never throw; if this is incorrect,
callers should unset TREE_NOTHROW. */
! tree
build_library_fn (tree name, tree type)
{
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
--- 3590,3596 ----
We assume that such functions never throw; if this is incorrect,
callers should unset TREE_NOTHROW. */
! static tree
build_library_fn (tree name, tree type)
{
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
*************** build_cp_library_fn_ptr (const char* nam
*** 3629,3640 ****
}
/* Like build_library_fn, but also pushes the function so that we will
! be able to find it via IDENTIFIER_GLOBAL_VALUE. */
tree
! push_library_fn (tree name, tree type)
{
! tree fn = build_library_fn (name, type);
pushdecl_top_level (fn);
return fn;
}
--- 3629,3646 ----
}
/* Like build_library_fn, but also pushes the function so that we will
! be able to find it via IDENTIFIER_GLOBAL_VALUE. Also, the function
! may throw exceptions listed in RAISES. */
tree
! push_library_fn (tree name, tree type, tree raises)
{
! tree fn;
!
! if (raises)
! type = build_exception_variant (type, raises);
!
! fn = build_library_fn (name, type);
pushdecl_top_level (fn);
return fn;
}
*************** tree
*** 3659,3665 ****
push_void_library_fn (tree name, tree parmtypes)
{
tree type = build_function_type (void_type_node, parmtypes);
! return push_library_fn (name, type);
}
/* Like push_library_fn, but also note that this function throws
--- 3665,3671 ----
push_void_library_fn (tree name, tree parmtypes)
{
tree type = build_function_type (void_type_node, parmtypes);
! return push_library_fn (name, type, NULL_TREE);
}
/* Like push_library_fn, but also note that this function throws
*************** push_void_library_fn (tree name, tree pa
*** 3668,3674 ****
tree
push_throw_library_fn (tree name, tree type)
{
! tree fn = push_library_fn (name, type);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
--- 3674,3680 ----
tree
push_throw_library_fn (tree name, tree type)
{
! tree fn = push_library_fn (name, type, NULL_TREE);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
*************** expand_static_init (tree decl, tree init
*** 6169,6177 ****
void_list_node);
tree vfntype = build_function_type (void_type_node, argtypes);
acquire_fn = push_library_fn
! (acquire_fn, build_function_type (integer_type_node, argtypes));
! release_fn = push_library_fn (release_fn, vfntype);
! abort_fn = push_library_fn (abort_fn, vfntype);
}
else
{
--- 6175,6184 ----
void_list_node);
tree vfntype = build_function_type (void_type_node, argtypes);
acquire_fn = push_library_fn
! (acquire_fn, build_function_type (integer_type_node, argtypes),
! NULL_TREE);
! release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
! abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
}
else
{
Index: except.c
===================================================================
*** except.c (revision 138187)
--- except.c (working copy)
***************
*** 1,6 ****
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
! 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
initial re-implementation courtesy Tad Hunt.
--- 1,7 ----
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
! 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
! Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
initial re-implementation courtesy Tad Hunt.
*************** build_exc_ptr (void)
*** 160,165 ****
--- 161,181 ----
return build0 (EXC_PTR_EXPR, ptr_type_node);
}
+ /* Declare a function NAME, returning RETURN_TYPE, taking a single
+ parameter PARM_TYPE, with an empty exception specification.
+
+ Note that the C++ ABI document does not have a throw-specifier on
+ the routines declared below via this function. The declarations
+ are consistent with the actual implementations in libsupc++. */
+
+ static tree
+ declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
+ {
+ tree tmp = tree_cons (NULL_TREE, parm_type, void_list_node);
+ return push_library_fn (name, build_function_type (return_type, tmp),
+ empty_except_spec);
+ }
+
/* Build up a call to __cxa_get_exception_ptr so that we can build a
copy constructor for the thrown object. */
*************** do_get_exception_ptr (void)
*** 171,179 ****
fn = get_identifier ("__cxa_get_exception_ptr");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void* __cxa_get_exception_ptr (void *). */
! tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
! fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
--- 187,194 ----
fn = get_identifier ("__cxa_get_exception_ptr");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
! fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
*************** do_begin_catch (void)
*** 192,200 ****
fn = get_identifier ("__cxa_begin_catch");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void* __cxa_begin_catch (void *). */
! tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
! fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
--- 207,214 ----
fn = get_identifier ("__cxa_begin_catch");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void* __cxa_begin_catch (void *) throw(). */
! fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
*************** do_allocate_exception (tree type)
*** 543,551 ****
fn = get_identifier ("__cxa_allocate_exception");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void *__cxa_allocate_exception(size_t). */
! tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
! fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
}
return cp_build_function_call (fn,
--- 557,564 ----
fn = get_identifier ("__cxa_allocate_exception");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void *__cxa_allocate_exception(size_t) throw(). */
! fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
}
return cp_build_function_call (fn,
*************** do_free_exception (tree ptr)
*** 565,573 ****
fn = get_identifier ("__cxa_free_exception");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void __cxa_free_exception (void *). */
! fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
! void_list_node));
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
--- 578,585 ----
fn = get_identifier ("__cxa_free_exception");
if (!get_global_value_if_present (fn, &fn))
{
! /* Declare void __cxa_free_exception (void *) throw(). */
! fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
Index: cp-tree.h
===================================================================
*** cp-tree.h (revision 138187)
--- cp-tree.h (working copy)
*************** extern bool check_omp_return (void);
*** 4225,4234 ****
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
extern tree check_for_out_of_scope_variable (tree);
- extern tree build_library_fn (tree, tree);
extern tree build_library_fn_ptr (const char *, tree);
extern tree build_cp_library_fn_ptr (const char *, tree);
! extern tree push_library_fn (tree, tree);
extern tree push_void_library_fn (tree, tree);
extern tree push_throw_library_fn (tree, tree);
extern tree check_tag_decl (cp_decl_specifier_seq *);
--- 4225,4233 ----
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
extern tree check_for_out_of_scope_variable (tree);
extern tree build_library_fn_ptr (const char *, tree);
extern tree build_cp_library_fn_ptr (const char *, tree);
! extern tree push_library_fn (tree, tree, tree);
extern tree push_void_library_fn (tree, tree);
extern tree push_throw_library_fn (tree, tree);
extern tree check_tag_decl (cp_decl_specifier_seq *);