OSDN Git Service

* cp-tree.h (struct tinst_level): Add chain_next GTY
[pf3gnuchains/gcc-fork.git] / gcc / cp / except.c
index 351e685..874f111 100644 (file)
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #include "flags.h"
 #include "output.h"
-#include "toplev.h"
 #include "tree-inline.h"
 #include "tree-iterator.h"
 #include "target.h"
@@ -295,9 +294,8 @@ decl_is_java_type (tree decl, int err)
 /* Select the personality routine to be used for exception handling,
    or issue an error if we need two different ones in the same
    translation unit.
-   ??? At present eh_personality_decl is set to
-   __gxx_personality_(sj|v)0 in init_exception_processing - should it
-   be done here instead?  */
+   ??? At present DECL_FUNCTION_PERSONALITY is set via
+   LANG_HOOKS_EH_PERSONALITY.  Should it be done here instead?  */
 void
 choose_personality_routine (enum languages lang)
 {
@@ -376,7 +374,7 @@ initialize_handler_parm (tree decl, tree exp)
      pointer catch parm with the address of the temporary.  */
   if (TREE_CODE (init_type) == REFERENCE_TYPE
       && TYPE_PTR_P (TREE_TYPE (init_type)))
-    exp = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
+    exp = cp_build_addr_expr (exp, tf_warning_or_error);
 
   exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
 
@@ -649,7 +647,9 @@ build_throw (tree exp)
     {
       if (cfun)
        current_function_returns_abnormally = 1;
-      return build_min (THROW_EXPR, void_type_node, exp);
+      exp = build_min (THROW_EXPR, void_type_node, exp);
+      SET_EXPR_LOCATION (exp, input_location);
+      return exp;
     }
 
   if (exp == null_node)
@@ -835,6 +835,7 @@ build_throw (tree exp)
     }
 
   exp = build1 (THROW_EXPR, void_type_node, exp);
+  SET_EXPR_LOCATION (exp, input_location);
 
   return exp;
 }
@@ -1052,15 +1053,20 @@ check_noexcept_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
 
       STRIP_NOPS (fn);
       if (TREE_CODE (fn) == ADDR_EXPR)
+       fn = TREE_OPERAND (fn, 0);
+      if (TREE_CODE (fn) == FUNCTION_DECL)
        {
          /* We do use TREE_NOTHROW for ABI internals like __dynamic_cast,
             and for C library functions known not to throw.  */
-         fn = TREE_OPERAND (fn, 0);
-         if (TREE_CODE (fn) == FUNCTION_DECL
-             && DECL_EXTERN_C_P (fn)
+         if (DECL_EXTERN_C_P (fn)
              && (DECL_ARTIFICIAL (fn)
                  || nothrow_libfn_p (fn)))
            return TREE_NOTHROW (fn) ? NULL_TREE : fn;
+         /* A call to a constexpr function is noexcept if the call
+            is a constant expression.  */
+         if (DECL_DECLARED_CONSTEXPR_P (fn)
+             && is_sub_constant_expr (t))
+           return NULL_TREE;
        }
       if (!TYPE_NOTHROW_P (type))
        return fn;
@@ -1119,6 +1125,9 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain)
 {
   tree fn;
 
+  if (expr == error_mark_node)
+    return error_mark_node;
+
   if (processing_template_decl)
     return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
 
@@ -1193,13 +1202,21 @@ type_throw_all_p (const_tree type)
 tree
 build_noexcept_spec (tree expr, int complain)
 {
-  expr = perform_implicit_conversion_flags (boolean_type_node, expr,
-                                           complain,
-                                           LOOKUP_NORMAL);
+  /* This isn't part of the signature, so don't bother trying to evaluate
+     it until instantiation.  */
+  if (!processing_template_decl)
+    {
+      expr = perform_implicit_conversion_flags (boolean_type_node, expr,
+                                               complain,
+                                               LOOKUP_NORMAL);
+      expr = cxx_constant_value (expr);
+    }
   if (expr == boolean_true_node)
     return noexcept_true_spec;
   else if (expr == boolean_false_node)
     return noexcept_false_spec;
+  else if (expr == error_mark_node)
+    return error_mark_node;
   else
     {
       gcc_assert (processing_template_decl || expr == error_mark_node);