diff gcc/jit/jit-playback.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line diff
--- a/gcc/jit/jit-playback.c	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/jit/jit-playback.c	Thu Feb 13 11:34:05 2020 +0900
@@ -1,5 +1,5 @@
 /* Internals of libgccjit: classes for playing back recorded API calls.
-   Copyright (C) 2013-2018 Free Software Foundation, Inc.
+   Copyright (C) 2013-2020 Free Software Foundation, Inc.
    Contributed by David Malcolm <dmalcolm@redhat.com>.
 
 This file is part of GCC.
@@ -47,6 +47,13 @@
 #include "jit-builtins.h"
 #include "jit-tempdir.h"
 
+/* Compare with gcc/c-family/c-common.h: DECL_C_BIT_FIELD,
+   SET_DECL_C_BIT_FIELD.
+   These are redefined here to avoid depending from the C frontend.  */
+#define DECL_JIT_BIT_FIELD(NODE) \
+  (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1)
+#define SET_DECL_JIT_BIT_FIELD(NODE) \
+  (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1)
 
 /* gcc::jit::playback::context::build_cast uses the convert.h API,
    which in turn requires the frontend to provide a "convert"
@@ -263,6 +270,46 @@
   return new field (decl);
 }
 
+/* Construct a playback::bitfield instance (wrapping a tree).  */
+
+playback::field *
+playback::context::
+new_bitfield (location *loc,
+	      type *type,
+	      int width,
+	      const char *name)
+{
+  gcc_assert (type);
+  gcc_assert (name);
+  gcc_assert (width);
+
+  /* compare with c/c-decl.c:grokfield,  grokdeclarator and
+     check_bitfield_type_and_width.  */
+
+  tree tree_type = type->as_tree ();
+  gcc_assert (INTEGRAL_TYPE_P (tree_type));
+  tree tree_width = build_int_cst (integer_type_node, width);
+  if (compare_tree_int (tree_width, TYPE_PRECISION (tree_type)) > 0)
+    {
+      add_error (
+	loc,
+	"width of bit-field %s (width: %i) is wider than its type (width: %i)",
+	name, width, TYPE_PRECISION (tree_type));
+      return NULL;
+    }
+
+  tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
+			  get_identifier (name), type->as_tree ());
+  DECL_NONADDRESSABLE_P (decl) = true;
+  DECL_INITIAL (decl) = tree_width;
+  SET_DECL_JIT_BIT_FIELD (decl);
+
+  if (loc)
+    set_tree_location (decl, loc);
+
+  return new field (decl);
+}
+
 /* Construct a playback::compound_type instance (wrapping a tree).  */
 
 playback::compound_type *
@@ -295,8 +342,15 @@
   for (unsigned i = 0; i < fields->length (); i++)
     {
       field *f = (*fields)[i];
-      DECL_CONTEXT (f->as_tree ()) = t;
-      fieldlist = chainon (f->as_tree (), fieldlist);
+      tree x = f->as_tree ();
+      DECL_CONTEXT (x) = t;
+      if (DECL_JIT_BIT_FIELD (x))
+	{
+	  unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x));
+	  DECL_SIZE (x) = bitsize_int (width);
+	  DECL_BIT_FIELD (x) = 1;
+	}
+      fieldlist = chainon (x, fieldlist);
     }
   fieldlist = nreverse (fieldlist);
   TYPE_FIELDS (t) = fieldlist;
@@ -399,12 +453,11 @@
 
   if (builtin_id)
     {
-      DECL_FUNCTION_CODE (fndecl) = builtin_id;
       gcc_assert (loc == NULL);
       DECL_SOURCE_LOCATION (fndecl) = BUILTINS_LOCATION;
 
-      DECL_BUILT_IN_CLASS (fndecl) =
-	builtins_manager::get_class (builtin_id);
+      built_in_class fclass = builtins_manager::get_class (builtin_id);
+      set_decl_built_in_function (fndecl, fclass, builtin_id);
       set_builtin_decl (builtin_id, fndecl,
 			builtins_manager::implicit_p (builtin_id));
 
@@ -1197,20 +1250,31 @@
   return new lvalue (get_context (), datum);
 }
 
-/* Mark EXP saying that we need to be able to take the
+/* Mark the lvalue saying that we need to be able to take the
    address of it; it should not be allocated in a register.
-   Compare with e.g. c/c-typeck.c: c_mark_addressable.  */
-
-static void
-jit_mark_addressable (tree exp)
+   Compare with e.g. c/c-typeck.c: c_mark_addressable really_atomic_lvalue.
+   Returns false if a failure occurred (an error will already have been
+   added to the active context for this case).  */
+
+bool
+playback::lvalue::
+mark_addressable (location *loc)
 {
-  tree x = exp;
+  tree x = as_tree ();;
 
   while (1)
     switch (TREE_CODE (x))
       {
       case COMPONENT_REF:
-	/* (we don't yet support bitfields)  */
+	if (DECL_JIT_BIT_FIELD (TREE_OPERAND (x, 1)))
+	  {
+	    gcc_assert (gcc::jit::active_playback_ctxt);
+	    gcc::jit::
+	      active_playback_ctxt->add_error (loc,
+					       "cannot take address of "
+					       "bit-field");
+	    return false;
+	  }
 	/* fallthrough */
       case ADDR_EXPR:
       case ARRAY_REF:
@@ -1222,7 +1286,7 @@
       case COMPOUND_LITERAL_EXPR:
       case CONSTRUCTOR:
 	TREE_ADDRESSABLE (x) = 1;
-	return;
+	return true;
 
       case VAR_DECL:
       case CONST_DECL:
@@ -1234,7 +1298,7 @@
 	TREE_ADDRESSABLE (x) = 1;
 	/* fallthrough */
       default:
-	return;
+	return true;
       }
 }
 
@@ -1251,8 +1315,10 @@
   tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
   if (loc)
     get_context ()->set_tree_location (ptr, loc);
-  jit_mark_addressable (t_lvalue);
-  return new rvalue (get_context (), ptr);
+  if (mark_addressable (loc))
+    return new rvalue (get_context (), ptr);
+  else
+    return NULL;
 }
 
 /* The wrapper subclasses are GC-managed, but can own non-GC memory.
@@ -2207,10 +2273,8 @@
   /* Aggressively garbage-collect, to shake out bugs: */
   if (get_bool_option (GCC_JIT_BOOL_OPTION_SELFCHECK_GC))
     {
-      ADD_ARG ("--param");
-      ADD_ARG ("ggc-min-expand=0");
-      ADD_ARG ("--param");
-      ADD_ARG ("ggc-min-heapsize=0");
+      ADD_ARG ("--param=ggc-min-expand=0");
+      ADD_ARG ("--param=ggc-min-heapsize=0");
     }
 
   if (get_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING))
@@ -2459,6 +2523,10 @@
   if (0)
     ADD_ARG ("-v");
 
+  /* Add any user-provided driver extra options.  */
+
+  m_recording_ctxt->append_driver_options (&argvec);
+
 #undef ADD_ARG
 
   /* pex_one's error-handling requires pname to be non-NULL.  */
@@ -2827,7 +2895,7 @@
   FOR_EACH_VEC_ELT (m_cached_locations, i, cached_location)
     {
       tree t = cached_location->first;
-      source_location srcloc = cached_location->second->m_srcloc;
+      location_t srcloc = cached_location->second->m_srcloc;
 
       /* This covers expressions: */
       if (CAN_HAVE_LOCATION_P (t))
@@ -2927,7 +2995,7 @@
 /* Deferred setting of the location for a given tree, by adding the
    (tree, playback::location) pair to a list of deferred associations.
    We will actually set the location on the tree later on once
-   the source_location for the playback::location exists.  */
+   the location_t for the playback::location exists.  */
 
 void
 playback::context::