OSDN Git Service

2009-08-04 David Daney <ddaney@caviumnetworks.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / expr.c
index c222a65..72ca773 100644 (file)
@@ -1,6 +1,6 @@
 /* Process expressions for the GNU compiler for the Java(TM) language.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -41,8 +41,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "parse.h"
 #include "toplev.h"
 #include "except.h"
+#include "tm_p.h"
 #include "ggc.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
 #include "target.h"
 
 static void flush_quick_stack (void);
@@ -430,28 +432,47 @@ type_assertion_eq (const void * k1_p, const void * k2_p)
 static hashval_t
 type_assertion_hash (const void *p)
 {
-  const type_assertion *k_p = p;
+  const type_assertion *k_p = (const type_assertion *) p;
   hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof
                                   k_p->assertion_code, 0);
-  hash = iterative_hash (&k_p->op1, sizeof k_p->op1, hash);
-  return iterative_hash (&k_p->op2, sizeof k_p->op2, hash);
+
+  switch (k_p->assertion_code)
+    {
+    case JV_ASSERT_TYPES_COMPATIBLE:
+      hash = iterative_hash (&TYPE_UID (k_p->op2), sizeof TYPE_UID (k_p->op2),
+                            hash);
+      /* Fall through.  */
+
+    case JV_ASSERT_IS_INSTANTIABLE:
+      hash = iterative_hash (&TYPE_UID (k_p->op1), sizeof TYPE_UID (k_p->op1),
+                            hash);
+      /* Fall through.  */
+
+    case JV_ASSERT_END_OF_TABLE:
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return hash;
 }
 
 /* Add an entry to the type assertion table for the given class.  
-   CLASS is the class for which this assertion will be evaluated by the 
+   KLASS is the class for which this assertion will be evaluated by the 
    runtime during loading/initialization.
    ASSERTION_CODE is the 'opcode' or type of this assertion: see java-tree.h.
    OP1 and OP2 are the operands. The tree type of these arguments may be
    specific to each assertion_code. */
 
 void
-add_type_assertion (tree class, int assertion_code, tree op1, tree op2)
+add_type_assertion (tree klass, int assertion_code, tree op1, tree op2)
 {
   htab_t assertions_htab;
   type_assertion as;
   void **as_pp;
 
-  assertions_htab = TYPE_ASSERTIONS (class);
+  assertions_htab = TYPE_ASSERTIONS (klass);
   if (assertions_htab == NULL)
     {
       assertions_htab = htab_create_ggc (7, type_assertion_hash, 
@@ -638,9 +659,8 @@ java_stack_swap (void)
   tree decl1, decl2;
 
   if (stack_pointer < 2
-      || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
-      || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
-      || type1 == TYPE_SECOND || type2 == TYPE_SECOND
+      || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_SECOND
+      || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_SECOND
       || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
     /* Bad stack swap.  */
     abort ();
@@ -649,7 +669,7 @@ java_stack_swap (void)
   flush_quick_stack ();
   decl1 = find_stack_slot (stack_pointer - 1, type1);
   decl2 = find_stack_slot (stack_pointer - 2, type2);
-  temp = build_decl (VAR_DECL, NULL_TREE, type1);
+  temp = build_decl (input_location, VAR_DECL, NULL_TREE, type1);
   java_add_local_var (temp);
   java_add_stmt (build2 (MODIFY_EXPR, type1, temp, decl1));
   java_add_stmt (build2 (MODIFY_EXPR, type2, 
@@ -796,10 +816,20 @@ encode_newarray_type (tree type)
 static tree
 build_java_throw_out_of_bounds_exception (tree index)
 {
-  tree node = build_call_nary (int_type_node,
+  tree node;
+
+  /* We need to build a COMPOUND_EXPR because _Jv_ThrowBadArrayIndex()
+     has void return type.  We cannot just set the type of the CALL_EXPR below
+     to int_type_node because we would lose it during gimplification.  */
+  gcc_assert (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (soft_badarrayindex_node))));
+  node = build_call_nary (void_type_node,
                               build_address_of (soft_badarrayindex_node),
                               1, index);
+  TREE_SIDE_EFFECTS (node) = 1;
+
+  node = build2 (COMPOUND_EXPR, int_type_node, node, integer_zero_node);
   TREE_SIDE_EFFECTS (node) = 1;        /* Allows expansion within ANDIF */
+
   return (node);
 }
 
@@ -875,7 +905,7 @@ build_java_indirect_ref (tree type, tree expr, int check)
 tree
 build_java_arrayaccess (tree array, tree type, tree index)
 {
-  tree node, throw = NULL_TREE;
+  tree node, throw_expr = NULL_TREE;
   tree data_field;
   tree ref;
   tree array_type = TREE_TYPE (TREE_TYPE (array));
@@ -903,17 +933,18 @@ build_java_arrayaccess (tree array, tree type, tree index)
                          len);
       if (! integer_zerop (test))
        {
-         throw = build2 (TRUTH_ANDIF_EXPR, int_type_node, test,
-                         build_java_throw_out_of_bounds_exception (index));
+         throw_expr
+           = build2 (TRUTH_ANDIF_EXPR, int_type_node, test,
+                     build_java_throw_out_of_bounds_exception (index));
          /* allows expansion within COMPOUND */
-         TREE_SIDE_EFFECTS( throw ) = 1;
+         TREE_SIDE_EFFECTS( throw_expr ) = 1;
        }
     }
 
   /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
      to have the bounds check evaluated first. */
-  if (throw != NULL_TREE)
-    index = build2 (COMPOUND_EXPR, int_type_node, throw, index);
+  if (throw_expr != NULL_TREE)
+    index = build2 (COMPOUND_EXPR, int_type_node, throw_expr, index);
 
   data_field = lookup_field (&array_type, get_identifier ("data"));
 
@@ -1161,7 +1192,7 @@ expand_java_arraystore (tree rhs_type_node)
      MODIFY_EXPR to set the array element.  */
 
   access = build_java_arrayaccess (array, rhs_type_node, index);
-  temp = build_decl (VAR_DECL, NULL_TREE, 
+  temp = build_decl (input_location, VAR_DECL, NULL_TREE, 
                     build_pointer_type (TREE_TYPE (access)));
   java_add_local_var (temp);
   java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (temp),
@@ -1301,7 +1332,7 @@ expand_load_internal (int index, tree type, int pc)
      generated.  To avoid this we create a new local and copy our
      value into it.  Then we push this new local on the stack.
      Hopefully this all gets optimized out.  */
-  copy = build_decl (VAR_DECL, NULL_TREE, type);
+  copy = build_decl (input_location, VAR_DECL, NULL_TREE, type);
   if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
       && TREE_TYPE (copy) != TREE_TYPE (var))
     var = convert (type, var);
@@ -1793,7 +1824,7 @@ tree
 create_label_decl (tree name)
 {
   tree decl;
-  decl = build_decl (LABEL_DECL, name, 
+  decl = build_decl (input_location, LABEL_DECL, name, 
                     TREE_TYPE (return_address_type_node));
   DECL_CONTEXT (decl) = current_function_decl;
   DECL_IGNORED_P (decl) = 1;
@@ -1876,7 +1907,7 @@ expand_java_switch (tree selector, int default_pc)
   java_add_stmt (switch_expr);
 
   x = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
-             create_artificial_label ());
+             create_artificial_label (input_location));
   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
 
   x = build1 (GOTO_EXPR, void_type_node, lookup_label (default_pc));
@@ -1893,7 +1924,7 @@ expand_java_add_case (tree switch_expr, int match, int target_pc)
   value = build_int_cst (TREE_TYPE (switch_expr), match);
   
   x = build3 (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
-             create_artificial_label ());
+             create_artificial_label (input_location));
   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
 
   x = build1 (GOTO_EXPR, void_type_node, lookup_label (target_pc));
@@ -1995,16 +2026,10 @@ build_class_init (tree clas, tree expr)
        {
          /* Build a declaration and mark it as a flag used to track
             static class initializations. */
-         decl = build_decl (VAR_DECL, NULL_TREE,
+         decl = build_decl (input_location, VAR_DECL, NULL_TREE,
                             boolean_type_node);
          MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
-         LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
          DECL_CONTEXT (decl) = current_function_decl;
-         DECL_FUNCTION_INIT_TEST_CLASS (decl) = clas;
-         /* Tell the check-init code to ignore this decl when not
-             optimizing class initialization. */
-         if (!STATIC_CLASS_INIT_OPT_P ())
-           DECL_BIT_INDEX (decl) = -1;
          DECL_INITIAL (decl) = boolean_false_node;
          /* Don't emit any symbolic debugging info for this decl.  */
          DECL_IGNORED_P (decl) = 1;      
@@ -2051,6 +2076,7 @@ typedef struct
   const char *classname;
   const char *method;
   const char *signature;
+  const char *new_classname;
   const char *new_signature;
   int flags;
   tree (*rewrite_arglist) (tree arglist);
@@ -2065,9 +2091,9 @@ rewrite_arglist_getcaller (tree arglist)
   tree retaddr 
     = build_call_expr (built_in_decls[BUILT_IN_RETURN_ADDRESS],
                       1, integer_zero_node);
-  
-  DECL_INLINE (current_function_decl) = 0;
 
+  DECL_UNINLINABLE (current_function_decl) = 1;
+  
   return chainon (arglist, 
                  tree_cons (NULL_TREE, retaddr, 
                             NULL_TREE));
@@ -2085,20 +2111,27 @@ rewrite_arglist_getclass (tree arglist)
 
 static rewrite_rule rules[] =
   {{"java.lang.Class", "getClassLoader", "()Ljava/lang/ClassLoader;", 
-    "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", 
+    "java.lang.Class", "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", 
     ACC_FINAL|ACC_PRIVATE, rewrite_arglist_getclass},
+
    {"java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
-    "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+    "java.lang.Class", "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getclass},
+
    {"gnu.classpath.VMStackWalker", "getCallingClass", "()Ljava/lang/Class;",
-    "(Lgnu/gcj/RawData;)Ljava/lang/Class;",
+    "gnu.classpath.VMStackWalker", "(Lgnu/gcj/RawData;)Ljava/lang/Class;",
     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getcaller},
+
    {"gnu.classpath.VMStackWalker", "getCallingClassLoader", 
     "()Ljava/lang/ClassLoader;",
-    "(Lgnu/gcj/RawData;)Ljava/lang/ClassLoader;",
+    "gnu.classpath.VMStackWalker", "(Lgnu/gcj/RawData;)Ljava/lang/ClassLoader;",
     ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getcaller},
 
-   {NULL, NULL, NULL, NULL, 0, NULL}};
+   {"gnu.java.lang.VMCPStringBuilder", "toString", "([CII)Ljava/lang/String;", 
+    "java.lang.String", "([CII)Ljava/lang/String;",
+    ACC_FINAL|ACC_PRIVATE|ACC_STATIC, NULL},
+
+   {NULL, NULL, NULL, NULL, NULL, 0, NULL}};
 
 /* True if this method is special, i.e. it's a private method that
    should be exported from a DSO.  */
@@ -2139,20 +2172,25 @@ maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
          if (get_identifier (p->method) == method
              && get_identifier (p->signature) == *method_signature_p)
            {
-             tree maybe_method
-               = lookup_java_method (DECL_CONTEXT (*method_p),
+             tree maybe_method;
+             tree destination_class 
+               = lookup_class (get_identifier (p->new_classname));
+             gcc_assert (destination_class);
+             maybe_method
+               = lookup_java_method (destination_class,
                                      method,
                                      get_identifier (p->new_signature));
              if (! maybe_method && ! flag_verify_invocations)
                {
                  maybe_method
-                   = add_method (DECL_CONTEXT (*method_p), p->flags, 
+                   = add_method (destination_class, p->flags, 
                                  method, get_identifier (p->new_signature));
                  DECL_EXTERNAL (maybe_method) = 1;
                }
              *method_p = maybe_method;
              gcc_assert (*method_p);
-             *arg_list_p = p->rewrite_arglist (*arg_list_p);
+             if (p->rewrite_arglist)
+               *arg_list_p = p->rewrite_arglist (*arg_list_p);
              *method_signature_p = get_identifier (p->new_signature);
              *special = integer_one_node;
 
@@ -2621,7 +2659,6 @@ build_jni_stub (tree method)
   int args_size = 0;
 
   tree klass = DECL_CONTEXT (method);
-  int from_class = ! CLASS_FROM_SOURCE_P (klass);
   klass = build_class_ref (klass);
 
   gcc_assert (METHOD_NATIVE (method) && flag_jni);
@@ -2629,47 +2666,28 @@ build_jni_stub (tree method)
   DECL_ARTIFICIAL (method) = 1;
   DECL_EXTERNAL (method) = 0;
 
-  env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
+  env_var = build_decl (input_location,
+                       VAR_DECL, get_identifier ("env"), ptr_type_node);
   DECL_CONTEXT (env_var) = method;
 
   if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
     {
-      res_var = build_decl (VAR_DECL, get_identifier ("res"),
+      res_var = build_decl (input_location, VAR_DECL, get_identifier ("res"),
                            TREE_TYPE (TREE_TYPE (method)));
       DECL_CONTEXT (res_var) = method;
       TREE_CHAIN (env_var) = res_var;
     }
 
-  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
-  TREE_STATIC (meth_var) = 1;
-  TREE_PUBLIC (meth_var) = 0;
-  DECL_EXTERNAL (meth_var) = 0;
-  DECL_CONTEXT (meth_var) = method;
-  DECL_ARTIFICIAL (meth_var) = 1;
-  DECL_INITIAL (meth_var) = null_pointer_node;
-  TREE_USED (meth_var) = 1;
-  chainon (env_var, meth_var);
-  build_result_decl (method);
-
-  /* One strange way that the front ends are different is that they
-     store arguments differently.  */
-  if (from_class)
-    method_args = DECL_ARGUMENTS (method);
-  else
-    method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
+  method_args = DECL_ARGUMENTS (method);
   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
   TREE_SIDE_EFFECTS (block) = 1;
-  /* When compiling from source we don't set the type of the block,
-     because that will prevent patch_return from ever being run.  */
-  if (from_class)
-    TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
+  TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
 
   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
   body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
                 build_call_nary (ptr_type_node,
                                  build_address_of (soft_getjnienvnewframe_node),
                                  1, klass));
-  CAN_COMPLETE_NORMALLY (body) = 1;
 
   /* All the arguments to this method become arguments to the
      underlying JNI function.  If we had to wrap object arguments in a
@@ -2723,23 +2741,41 @@ build_jni_stub (tree method)
 
   jni_func_type = build_pointer_type (tem);
 
-  jnifunc = build3 (COND_EXPR, ptr_type_node,
+  /* Use the actual function type, rather than a generic pointer type,
+     such that this decl keeps the actual pointer type from being
+     garbage-collected.  If it is, we end up using canonical types
+     with different uids for equivalent function types, and this in
+     turn causes utf8 identifiers and output order to vary.  */
+  meth_var = build_decl (input_location,
+                        VAR_DECL, get_identifier ("meth"), jni_func_type);
+  TREE_STATIC (meth_var) = 1;
+  TREE_PUBLIC (meth_var) = 0;
+  DECL_EXTERNAL (meth_var) = 0;
+  DECL_CONTEXT (meth_var) = method;
+  DECL_ARTIFICIAL (meth_var) = 1;
+  DECL_INITIAL (meth_var) = null_pointer_node;
+  TREE_USED (meth_var) = 1;
+  chainon (env_var, meth_var);
+  build_result_decl (method);
+
+  jnifunc = build3 (COND_EXPR, jni_func_type,
                    build2 (NE_EXPR, boolean_type_node,
                            meth_var, build_int_cst (TREE_TYPE (meth_var), 0)),
                    meth_var,
-                   build2 (MODIFY_EXPR, ptr_type_node, meth_var,
-                           build_call_nary (ptr_type_node,
-                                            build_address_of
-                                              (soft_lookupjnimethod_node),
-                                            4,
-                                            jniarg0, jniarg1,
-                                            jniarg2, jniarg3)));
+                   build2 (MODIFY_EXPR, jni_func_type, meth_var,
+                           build1
+                           (NOP_EXPR, jni_func_type,
+                            build_call_nary (ptr_type_node,
+                                             build_address_of
+                                             (soft_lookupjnimethod_node),
+                                             4,
+                                             jniarg0, jniarg1,
+                                             jniarg2, jniarg3))));
 
   /* Now we make the actual JNI call via the resulting function
      pointer.    */
   call = build_call_list (TREE_TYPE (TREE_TYPE (method)),
-                         build1 (NOP_EXPR, jni_func_type, jnifunc),
-                         args);
+                         jnifunc, args);
 
   /* If the JNI call returned a result, capture it here.  If we had to
      unwrap JNI object results, we would do that here.  */
@@ -2756,7 +2792,6 @@ build_jni_stub (tree method)
     }
 
   TREE_SIDE_EFFECTS (call) = 1;
-  CAN_COMPLETE_NORMALLY (call) = 1;
 
   body = build2 (COMPOUND_EXPR, void_type_node, body, call);
   TREE_SIDE_EFFECTS (body) = 1;
@@ -2766,7 +2801,6 @@ build_jni_stub (tree method)
                          build_address_of (soft_jnipopsystemframe_node),
                          1, env_var);
   TREE_SIDE_EFFECTS (call) = 1;
-  CAN_COMPLETE_NORMALLY (call) = 1;
   body = build2 (COMPOUND_EXPR, void_type_node, body, call);
   TREE_SIDE_EFFECTS (body) = 1;
 
@@ -2939,7 +2973,8 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
     }
   else
     {
-      tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
+      tree temp = build_decl (input_location,
+                             VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
       java_add_local_var (temp);
 
       if (TREE_THIS_VOLATILE (field_decl))
@@ -3003,7 +3038,7 @@ note_instructions (JCF *jcf, tree method)
 
   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
   byte_ops = jcf->read_ptr;
-  instruction_bits = xrealloc (instruction_bits, length + 1);
+  instruction_bits = XRESIZEVAR (char, instruction_bits, length + 1);
   memset (instruction_bits, 0, length + 1);
   type_states = VEC_alloc (tree, gc, length + 1);
   VEC_safe_grow_cleared (tree, gc, type_states, length + 1);
@@ -3126,6 +3161,7 @@ expand_byte_code (JCF *jcf, tree method)
   int dead_code_index = -1;
   unsigned char* byte_ops;
   long length = DECL_CODE_LENGTH (method);
+  location_t max_location = input_location;
 
   stack_pointer = 0;
   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
@@ -3212,11 +3248,9 @@ expand_byte_code (JCF *jcf, tree method)
              if (pc == PC)
                {
                  int line = GET_u2 (linenumber_pointer - 2);
-#ifdef USE_MAPPED_LOCATION
-                 input_location = linemap_line_start (&line_table, line, 1);
-#else
-                 input_location.line = line;
-#endif
+                 input_location = linemap_line_start (line_table, line, 1);
+                 if (input_location > max_location)
+                   max_location = input_location;
                  if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
                    break;
                }
@@ -3236,6 +3270,8 @@ expand_byte_code (JCF *jcf, tree method)
        warning (0, "unreachable bytecode from %d to the end of the method", 
                 dead_code_index);
     }
+
+  DECL_FUNCTION_LAST_LINE (method) = max_location;
 }
 
 static void
@@ -3440,9 +3476,9 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
   }
 #define ARRAY_NEW_MULTI()                                      \
   {                                                            \
-    tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );      \
+    tree klass = get_class_constant (current_jcf, IMMEDIATE_u2 );      \
     int  ndims = IMMEDIATE_u1;                                 \
-    expand_java_multianewarray( class, ndims );                        \
+    expand_java_multianewarray( klass, ndims );                        \
   }
 
 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
@@ -3750,7 +3786,6 @@ force_evaluation_order (tree node)
          cmp = build2 (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
          if (TREE_TYPE (cmp) != void_type_node)
            cmp = save_expr (cmp);
-         CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
          TREE_SIDE_EFFECTS (cmp) = 1;
          node = cmp;
        }
@@ -3763,8 +3798,7 @@ force_evaluation_order (tree node)
 tree
 build_java_empty_stmt (void)
 {
-  tree t = build_empty_stmt ();
-  CAN_COMPLETE_NORMALLY (t) = 1;
+  tree t = build_empty_stmt (input_location);
   return t;
 }
 
@@ -3801,10 +3835,9 @@ cache_cpool_data_ref (void)
     {
       tree cpool;
       tree d = build_constant_data_ref (flag_indirect_classes);
-      tree cpool_ptr = build_decl (VAR_DECL, NULL_TREE, 
+      tree cpool_ptr = build_decl (input_location, VAR_DECL, NULL_TREE, 
                                   build_pointer_type (TREE_TYPE (d)));
       java_add_local_var (cpool_ptr);
-      TREE_INVARIANT (cpool_ptr) = 1;
       TREE_CONSTANT (cpool_ptr) = 1;
 
       java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (cpool_ptr),