OSDN Git Service

PR tree-optimization/16867
[pf3gnuchains/gcc-fork.git] / gcc / tree-mudflap.c
index adfb3c7..4f8e174 100644 (file)
@@ -195,10 +195,11 @@ mf_file_function_line_tree (location_t location)
   tree result;
 
   /* Add FILENAME[:LINENUMBER]. */
-  if (xloc.file == NULL && current_function_decl != NULL_TREE)
-    xloc.file = DECL_SOURCE_FILE (current_function_decl);
-  if (xloc.file == NULL)
-    xloc.file = "<unknown file>";
+  file = xloc.file;
+  if (file == NULL && current_function_decl != NULL_TREE)
+    file = DECL_SOURCE_FILE (current_function_decl);
+  if (file == NULL)
+    file = "<unknown file>";
 
   if (xloc.line > 0)
     {
@@ -271,6 +272,10 @@ static GTY (()) tree mf_unregister_fndecl;
 /* extern void __mf_init (); */
 static GTY (()) tree mf_init_fndecl;
 
+/* extern int __mf_set_options (const char*); */
+static GTY (()) tree mf_set_options_fndecl;
+
+
 /* Helper for mudflap_init: construct a decl with the given category,
    name, and type, mark it an external reference, and pushdecl it.  */
 static inline tree
@@ -308,6 +313,8 @@ mf_make_mf_cache_struct_type (tree field_type)
 
 #define build_function_type_0(rtype)            \
   build_function_type (rtype, void_list_node)
+#define build_function_type_1(rtype, arg1)                 \
+  build_function_type (rtype, tree_cons (0, arg1, void_list_node))
 #define build_function_type_3(rtype, arg1, arg2, arg3)                  \
   build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2,   \
                                                              tree_cons (0, arg3, void_list_node))))
@@ -327,6 +334,7 @@ mudflap_init (void)
   tree mf_check_register_fntype;
   tree mf_unregister_fntype;
   tree mf_init_fntype;
+  tree mf_set_options_fntype;
 
   if (done)
     return;
@@ -349,6 +357,8 @@ mudflap_init (void)
                            integer_type_node);
   mf_init_fntype =
     build_function_type_0 (void_type_node);
+  mf_set_options_fntype =
+    build_function_type_1 (integer_type_node, mf_const_string_type);
 
   mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache",
                                          mf_cache_array_type);
@@ -364,9 +374,12 @@ mudflap_init (void)
                                           mf_unregister_fntype);
   mf_init_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_init",
                                     mf_init_fntype);
+  mf_set_options_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_set_options",
+                                           mf_set_options_fntype);
 }
 #undef build_function_type_4
 #undef build_function_type_3
+#undef build_function_type_1
 #undef build_function_type_0
 
 
@@ -884,6 +897,8 @@ mx_register_decls (tree decl, tree *stmt_list)
           && TREE_ADDRESSABLE (decl)
           /* The type of the variable must be complete.  */
           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
+         /* The decl hasn't been decomposed somehow.  */
+         && DECL_VALUE_EXPR (decl) == NULL
           /* Don't process the same decl twice.  */
           && ! mf_marked_p (decl))
         {
@@ -891,73 +906,7 @@ mx_register_decls (tree decl, tree *stmt_list)
           tree unregister_fncall, unregister_fncall_params;
           tree register_fncall, register_fncall_params;
 
-          if (DECL_DEFER_OUTPUT (decl))
-            {
-              /* Oh no ... it's probably a variable-length array (VLA).
-                 The size and address cannot be computed by merely
-                 looking at the DECL.  See gimplify_decl_stmt for the
-                 method by which VLA declarations turn into calls to
-                 BUILT_IN_STACK_ALLOC.  We assume that multiple
-                 VLAs declared later in the same block get allocation 
-                 code later than the others.  */
-              tree stack_alloc_call = NULL_TREE;
-
-              while(! tsi_end_p (initially_stmts))
-                {
-                  tree t = tsi_stmt (initially_stmts);
-
-                  tree call = NULL_TREE;
-                  if (TREE_CODE (t) == CALL_EXPR)
-                    call = t;
-                  else if (TREE_CODE (t) == MODIFY_EXPR &&
-                           TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
-                    call = TREE_OPERAND (t, 1);
-                  else if (TREE_CODE (t) == TRY_FINALLY_EXPR)
-                    {
-                      /* We hope that this is the try/finally block sometimes
-                         constructed by gimplify_bind_expr() for a BIND_EXPR
-                         that contains VLAs.  This very naive recursion
-                         appears to be sufficient.  */
-                      initially_stmts = tsi_start (TREE_OPERAND (t, 0));
-                    }
-
-                  if (call != NULL_TREE)
-                    {
-                      if (TREE_CODE (TREE_OPERAND(call, 0)) == ADDR_EXPR &&
-                          TREE_OPERAND (TREE_OPERAND (call, 0), 0) ==
-                                implicit_built_in_decls [BUILT_IN_STACK_ALLOC])
-                        {
-                          tree stack_alloc_args = TREE_OPERAND (call, 1);
-                          tree stack_alloc_op1 = TREE_VALUE (stack_alloc_args);
-                          tree stack_alloc_op2 = TREE_VALUE (TREE_CHAIN (stack_alloc_args));
-                          
-                          if (TREE_CODE (stack_alloc_op1) == ADDR_EXPR &&
-                              TREE_OPERAND (stack_alloc_op1, 0) == decl)
-                            {
-                              /* Got it! */
-                              size = stack_alloc_op2;
-                              stack_alloc_call = call;
-                              /* Advance iterator to point past this allocation call.  */
-                              tsi_next (&initially_stmts);
-                              break;
-                            }
-                        }
-                    }
-
-                  tsi_next (&initially_stmts);
-                }
-
-              if (stack_alloc_call == NULL_TREE)
-                {
-                  warning ("mudflap cannot handle variable-sized declaration `%s'",
-                         IDENTIFIER_POINTER (DECL_NAME (decl)));
-                  break;
-                }
-            }
-          else
-            {
-              size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
-            }
+         size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
 
           /* (& VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
           unregister_fncall_params =
@@ -1141,13 +1090,6 @@ mudflap_register_call (tree obj, tree object_size, tree varname)
 
   call_stmt = build_function_call_expr (mf_register_fndecl, args);
 
-  /* Add an initial __mf_init() call to the list of registration calls.  */ 
-  if (enqueued_call_stmt_chain == NULL_TREE)
-    {
-      tree call2_stmt = build_function_call_expr (mf_init_fndecl, NULL_TREE);
-      append_to_statement_list (call2_stmt, &enqueued_call_stmt_chain);      
-    }
-
   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
 }
 
@@ -1244,6 +1186,8 @@ mudflap_enqueue_constant (tree obj)
 void
 mudflap_finish_file (void)
 {
+  tree ctor_statements = NULL_TREE;
+
   /* Try to give the deferred objects one final try.  */
   if (deferred_static_decls)
     {
@@ -1262,12 +1206,30 @@ mudflap_finish_file (void)
       VARRAY_CLEAR (deferred_static_decls);
     }
 
+  /* Insert a call to __mf_init.  */
+  {
+    tree call2_stmt = build_function_call_expr (mf_init_fndecl, NULL_TREE);
+    append_to_statement_list (call2_stmt, &ctor_statements);
+  }
+  
+  /* If appropriate, call __mf_set_options to pass along read-ignore mode.  */
+  if (flag_mudflap_ignore_reads)
+    {
+      tree arg = tree_cons (NULL_TREE, 
+                            mf_build_string ("-ignore-reads"), NULL_TREE);
+      tree call_stmt = build_function_call_expr (mf_set_options_fndecl, arg);
+      append_to_statement_list (call_stmt, &ctor_statements);
+    }
+
+  /* Append all the enqueued registration calls.  */
   if (enqueued_call_stmt_chain)
     {
-      cgraph_build_static_cdtor ('I', enqueued_call_stmt_chain, 
-                                 MAX_RESERVED_INIT_PRIORITY-1);
-      enqueued_call_stmt_chain = 0;
+      append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements);
+      enqueued_call_stmt_chain = NULL_TREE;
     }
+
+  cgraph_build_static_cdtor ('I', ctor_statements, 
+                             MAX_RESERVED_INIT_PRIORITY-1);
 }