* class.c (build_vtbl_initializer): Make __cxa_deleted_virtual
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Aug 2013 08:14:37 +0000 (08:14 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Aug 2013 08:14:37 +0000 (08:14 +0000)
ECF_NORETURN | ECF_LEAF
* cp-tree.h (build_library_fn_ptr, build_cp_library_fn_ptr,
push_library_fn, push_void_library_fn): Update prototype.
* decl.c (build_library_fn_1): Remove.
(push_cp_library_fn, build_cp_library_fn): Update to take ECF flags.
(cxx_init_decl_processing): Update; global_delete_fndecl is ECF_NOTROW;
__cxa_pure_virtual is ECF_NORETURN | ECF_NORETURN | ECF_LEAF.
(build_library_fn_1): Add ecf_flags argument; rename to ...
(build_library_fn): ... this one.
(build_cp_library_fn): Take ecf_flags; do not copy NOTHROW flag.
(build_library_fn_ptr): Take ecf_flags.
(build_cp_library_fn_ptr): Likewise.
(push_library_fn): Likewise.
(push_cp_library_fn): Likewise.
(push_void_library_fn): Likewise.
(push_throw_library_fn): All throws are ECF_NORETURN.
(__cxa_atexit, __cxa_thread_atexit): Add ECF_LEAF | ECF_NOTHROW attributes.
(expand_static_init): __cxa_guard_acquire, __cxa_guard_release,
__cxa_guard_abort are ECF_NOTHROW | ECF_LEAF.
* except.c (init_exception_processing): terminate is
ECF_NOTHROW | ECF_NORETURN | ECF_LEAF.
(declare_nothrow_library_fn): Add ecf_flags parameter.
(__cxa_get_exception_ptr): Is ECF_NOTHROW | ECF_PURE | ECF_LEAF |
ECF_TM_PURE.
(do_begin_catch): cxa_begin_catch and _ITM_cxa_begin_catch
are ECF_NOTHROW | ECF_LEAF.
(do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is
ECF_LEAF.
(do_allocate_exception): _cxa_allocate_exception
and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC
| ECF_LEAF
(do_free_exception): __cxa_free_exception is
ECF_NOTHROW | ECF_LEAF.
* rtti.c (build_dynamic_cast_1): __dynamic_cast
is ECF_LEAF | ECF_PURE | ECF_NOTHROW.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202099 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/rtti.c

index f848b81..2b2f45a 100644 (file)
@@ -1,3 +1,42 @@
+2013-08-29  Jan Hubicka  <jh@suse.cz>
+
+       * class.c (build_vtbl_initializer): Make __cxa_deleted_virtual
+       ECF_NORETURN | ECF_LEAF
+       * cp-tree.h (build_library_fn_ptr, build_cp_library_fn_ptr,
+       push_library_fn, push_void_library_fn): Update prototype.
+       * decl.c (build_library_fn_1): Remove.
+       (push_cp_library_fn, build_cp_library_fn): Update to take ECF flags.
+       (cxx_init_decl_processing): Update; global_delete_fndecl is ECF_NOTROW;
+       __cxa_pure_virtual is ECF_NORETURN | ECF_NORETURN | ECF_LEAF.
+       (build_library_fn_1): Add ecf_flags argument; rename to ...
+       (build_library_fn): ... this one.
+       (build_cp_library_fn): Take ecf_flags; do not copy NOTHROW flag.
+       (build_library_fn_ptr): Take ecf_flags.
+       (build_cp_library_fn_ptr): Likewise.
+       (push_library_fn): Likewise.
+       (push_cp_library_fn): Likewise.
+       (push_void_library_fn): Likewise.
+       (push_throw_library_fn): All throws are ECF_NORETURN.
+       (__cxa_atexit, __cxa_thread_atexit): Add ECF_LEAF | ECF_NOTHROW attributes.
+       (expand_static_init): __cxa_guard_acquire, __cxa_guard_release,
+       __cxa_guard_abort are ECF_NOTHROW | ECF_LEAF.
+       * except.c (init_exception_processing): terminate is
+       ECF_NOTHROW | ECF_NORETURN | ECF_LEAF.
+       (declare_nothrow_library_fn): Add ecf_flags parameter.
+       (__cxa_get_exception_ptr): Is ECF_NOTHROW | ECF_PURE | ECF_LEAF |
+       ECF_TM_PURE.
+       (do_begin_catch): cxa_begin_catch and _ITM_cxa_begin_catch
+       are ECF_NOTHROW | ECF_LEAF.
+       (do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is
+       ECF_LEAF.
+       (do_allocate_exception): _cxa_allocate_exception
+       and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC
+       | ECF_LEAF
+       (do_free_exception): __cxa_free_exception is
+       ECF_NOTHROW | ECF_LEAF.
+       * rtti.c (build_dynamic_cast_1): __dynamic_cast
+       is ECF_LEAF | ECF_PURE | ECF_NOTHROW.
+
 2013-08-29  Adam Butcher  <adam@jessamine.co.uk>
 
        * error.c (dump_lambda_function): New function, dependent on ...
index 596b13d..3f77d22 100644 (file)
@@ -8873,7 +8873,7 @@ build_vtbl_initializer (tree binfo,
              if (!get_global_value_if_present (fn, &fn))
                fn = push_library_fn (fn, (build_function_type_list
                                           (void_type_node, NULL_TREE)),
-                                     NULL_TREE);
+                                     NULL_TREE, ECF_NORETURN | ECF_LEAF);
              if (!TARGET_VTABLE_USES_DESCRIPTORS)
                init = fold_convert (vfunc_ptr_type_node,
                                     build_fold_addr_expr (fn));
index 876a72a..73f6a6a 100644 (file)
@@ -5170,10 +5170,10 @@ extern void check_goto                          (tree);
 extern bool check_omp_return                   (void);
 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 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 build_library_fn_ptr               (const char *, tree, int);
+extern tree build_cp_library_fn_ptr            (const char *, tree, int);
+extern tree push_library_fn                    (tree, tree, tree, int);
+extern tree push_void_library_fn               (tree, tree, int);
 extern tree push_throw_library_fn              (tree, tree);
 extern void warn_misplaced_attr_for_class_type  (source_location location,
                                                 tree class_type);
index 4076a24..bead6e8 100644 (file)
@@ -75,7 +75,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
-static tree build_library_fn_1 (tree, enum tree_code, tree);
 static int member_function_or_else (tree, tree, enum overload_flags);
 static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
                            int);
@@ -107,8 +106,8 @@ static tree cp_make_fname_decl (location_t, tree, int);
 static void initialize_predefined_identifiers (void);
 static tree check_special_function_return_type
        (special_function_kind, tree, tree);
-static tree push_cp_library_fn (enum tree_code, tree);
-static tree build_cp_library_fn (tree, enum tree_code, tree);
+static tree push_cp_library_fn (enum tree_code, tree, int);
+static tree build_cp_library_fn (tree, enum tree_code, tree, int);
 static void store_parm_decls (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
@@ -3800,10 +3799,10 @@ cxx_init_decl_processing (void)
     newtype = build_exception_variant (newtype, new_eh_spec);
     deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
     deltype = build_exception_variant (deltype, empty_except_spec);
-    push_cp_library_fn (NEW_EXPR, newtype);
-    push_cp_library_fn (VEC_NEW_EXPR, newtype);
-    global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
-    push_cp_library_fn (VEC_DELETE_EXPR, deltype);
+    push_cp_library_fn (NEW_EXPR, newtype, 0);
+    push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
+    global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+    push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
 
     nullptr_type_node = make_node (NULLPTR_TYPE);
     TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
@@ -3816,7 +3815,8 @@ cxx_init_decl_processing (void)
   }
 
   abort_fndecl
-    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
+    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
+                           ECF_NORETURN | ECF_NOTHROW | ECF_LEAF);
 
   /* Perform other language dependent initializations.  */
   init_class_processing ();
@@ -4007,7 +4007,8 @@ cxx_builtin_function_ext_scope (tree decl)
    function.  Not called directly.  */
 
 static tree
-build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
+build_library_fn (tree name, enum tree_code operator_code, tree type,
+                 int ecf_flags)
 {
   tree fn = build_lang_decl (FUNCTION_DECL, name, type);
   DECL_EXTERNAL (fn) = 1;
@@ -4019,28 +4020,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
      external shared object.  */
   DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
   DECL_VISIBILITY_SPECIFIED (fn) = 1;
-  return fn;
-}
-
-/* Returns the _DECL for a library function with C linkage.
-   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);
-  TREE_NOTHROW (fn) = 1;
+  set_call_expr_flags (fn, ecf_flags);
   return fn;
 }
 
 /* Returns the _DECL for a library function with C++ linkage.  */
 
 static tree
-build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
+                    int ecf_flags)
 {
-  tree fn = build_library_fn_1 (name, operator_code, type);
-  TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
+  tree fn = build_library_fn (name, operator_code, type, ecf_flags);
   DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
   SET_DECL_LANGUAGE (fn, lang_cplusplus);
   return fn;
@@ -4050,18 +4040,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
    IDENTIFIER_NODE.  */
 
 tree
-build_library_fn_ptr (const char* name, tree type)
+build_library_fn_ptr (const char* name, tree type, int ecf_flags)
 {
-  return build_library_fn (get_identifier (name), type);
+  return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
 }
 
 /* Like build_cp_library_fn, but takes a C string instead of an
    IDENTIFIER_NODE.  */
 
 tree
-build_cp_library_fn_ptr (const char* name, tree type)
+build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
 {
-  return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
+  return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
+                             ecf_flags);
 }
 
 /* Like build_library_fn, but also pushes the function so that we will
@@ -4069,14 +4060,14 @@ build_cp_library_fn_ptr (const char* name, tree type)
    may throw exceptions listed in RAISES.  */
 
 tree
-push_library_fn (tree name, tree type, tree raises)
+push_library_fn (tree name, tree type, tree raises, int ecf_flags)
 {
   tree fn;
 
   if (raises)
     type = build_exception_variant (type, raises);
 
-  fn = build_library_fn (name, type);
+  fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
   pushdecl_top_level (fn);
   return fn;
 }
@@ -4085,11 +4076,12 @@ push_library_fn (tree name, tree type, tree raises)
    will be found by normal lookup.  */
 
 static tree
-push_cp_library_fn (enum tree_code operator_code, tree type)
+push_cp_library_fn (enum tree_code operator_code, tree type,
+                   int ecf_flags)
 {
   tree fn = build_cp_library_fn (ansi_opname (operator_code),
                                 operator_code,
-                                type);
+                                type, ecf_flags);
   pushdecl (fn);
   if (flag_tm)
     apply_tm_attr (fn, get_identifier ("transaction_safe"));
@@ -4100,10 +4092,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type)
    a FUNCTION_TYPE.  */
 
 tree
-push_void_library_fn (tree name, tree parmtypes)
+push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
 {
   tree type = build_function_type (void_type_node, parmtypes);
-  return push_library_fn (name, type, NULL_TREE);
+  return push_library_fn (name, type, NULL_TREE, ecf_flags);
 }
 
 /* Like push_library_fn, but also note that this function throws
@@ -4112,9 +4104,7 @@ push_void_library_fn (tree name, tree parmtypes)
 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;
+  tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN | ECF_LEAF);
   return fn;
 }
 \f
@@ -6644,7 +6634,7 @@ get_atexit_node (void)
 
   /* Now, build the function declaration.  */
   push_lang_context (lang_name_c);
-  atexit_fndecl = build_library_fn_ptr (name, fn_type);
+  atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
   mark_used (atexit_fndecl);
   pop_lang_context ();
   atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
@@ -6666,7 +6656,8 @@ get_thread_atexit_node (void)
                                           NULL_TREE);
 
   /* Now, build the function declaration.  */
-  tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type);
+  tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
+                                            ECF_LEAF | ECF_NOTHROW);
   return decay_conversion (atexit_fndecl, tf_warning_or_error);
 }
 
@@ -6992,15 +6983,17 @@ expand_static_init (tree decl, tree init)
              (acquire_name, build_function_type_list (integer_type_node,
                                                       TREE_TYPE (guard_addr),
                                                       NULL_TREE),
-              NULL_TREE);
+              NULL_TREE, ECF_NOTHROW | ECF_LEAF);
          if (!release_fn || !abort_fn)
            vfntype = build_function_type_list (void_type_node,
                                                TREE_TYPE (guard_addr),
                                                NULL_TREE);
          if (!release_fn)
-           release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+           release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
+                                          ECF_NOTHROW | ECF_LEAF);
          if (!abort_fn)
-           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
+           abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
+                                       ECF_NOTHROW | ECF_LEAF);
 
          inner_if_stmt = begin_if_stmt ();
          finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
index be003d2..164b35c 100644 (file)
@@ -57,7 +57,9 @@ init_exception_processing (void)
   /* void std::terminate (); */
   push_namespace (std_identifier);
   tmp = build_function_type_list (void_type_node, NULL_TREE);
-  terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
+  terminate_node = build_cp_library_fn_ptr ("terminate", tmp,
+                                           ECF_NOTHROW | ECF_NORETURN
+                                           | ECF_LEAF);
   TREE_THIS_VOLATILE (terminate_node) = 1;
   TREE_NOTHROW (terminate_node) = 1;
   pop_namespace ();
@@ -149,12 +151,13 @@ build_exc_ptr (void)
    are consistent with the actual implementations in libsupc++.  */
 
 static tree
-declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
+declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
 {
   return push_library_fn (name, build_function_type_list (return_type,
                                                          parm_type,
                                                          NULL_TREE),
-                         empty_except_spec);
+                         empty_except_spec,
+                         ecf_flags);
 }
 
 /* Build up a call to __cxa_get_exception_ptr so that we can build a
@@ -169,10 +172,8 @@ do_get_exception_ptr (void)
   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);
-
-      if (flag_tm)
-       apply_tm_attr (fn, get_identifier ("transaction_pure"));
+      fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
+                              ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
     }
 
   return cp_build_function_call_nary (fn, tf_warning_or_error,
@@ -191,16 +192,17 @@ do_begin_catch (void)
   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);
+      fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
+                              ECF_NOTHROW | ECF_LEAF);
 
       /* Create its transactional-memory equivalent.  */
       if (flag_tm)
        {
          tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
          if (!get_global_value_if_present (fn2, &fn2))
-           fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
-                                             ptr_type_node);
-         apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+           fn2 = declare_library_fn (fn2, ptr_type_node,
+                                     ptr_type_node,
+                                     ECF_NOTHROW | ECF_TM_PURE | ECF_LEAF);
          record_tm_replacement (fn, fn2);
        }
     }
@@ -238,21 +240,17 @@ do_end_catch (tree type)
   fn = get_identifier ("__cxa_end_catch");
   if (!get_global_value_if_present (fn, &fn))
     {
-      /* Declare void __cxa_end_catch ().  */
-      fn = push_void_library_fn (fn, void_list_node);
-      /* This can throw if the destructor for the exception throws.  */
-      TREE_NOTHROW (fn) = 0;
+      /* Declare void __cxa_end_catch ().
+         This can throw if the destructor for the exception throws.  */
+      fn = push_void_library_fn (fn, void_list_node, ECF_LEAF);
 
       /* Create its transactional-memory equivalent.  */
       if (flag_tm)
        {
          tree fn2 = get_identifier ("_ITM_cxa_end_catch");
          if (!get_global_value_if_present (fn2, &fn2))
-           {
-             fn2 = push_void_library_fn (fn2, void_list_node);
-             TREE_NOTHROW (fn2) = 0;
-           }
-         apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+           fn2 = push_void_library_fn (fn2, void_list_node,
+                                       ECF_TM_PURE | ECF_LEAF);
          record_tm_replacement (fn, fn2);
        }
     }
@@ -631,15 +629,17 @@ do_allocate_exception (tree type)
   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);
+      fn = declare_library_fn (fn, ptr_type_node, size_type_node,
+                               ECF_NOTHROW | ECF_MALLOC | ECF_LEAF);
 
       if (flag_tm)
        {
          tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
          if (!get_global_value_if_present (fn2, &fn2))
-           fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
-                                             size_type_node);
-         apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+           fn2 = declare_library_fn (fn2, ptr_type_node,
+                                     size_type_node, 
+                                     ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE 
+                                     | ECF_LEAF);
          record_tm_replacement (fn, fn2);
        }
     }
@@ -660,7 +660,8 @@ do_free_exception (tree ptr)
   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);
+      fn = declare_library_fn (fn, void_type_node, ptr_type_node,
+                              ECF_NOTHROW | ECF_LEAF);
     }
 
   return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
index f309498..5827540 100644 (file)
@@ -739,8 +739,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
                                              const_ptr_type_node,
                                              tinfo_ptr, tinfo_ptr,
                                              ptrdiff_type_node, NULL_TREE);
-             dcast_fn = build_library_fn_ptr (name, tmp);
-             DECL_PURE_P (dcast_fn) = 1;
+             dcast_fn = build_library_fn_ptr (name, tmp,
+                                              ECF_LEAF | ECF_PURE | ECF_NOTHROW);
              pop_abi_namespace ();
              dynamic_cast_node = dcast_fn;
            }