diff mbox series

[d] Committed refactor building typeof(null) value.

Message ID CABOHX+dfJEDWe+vb9XGU4CA3aWt93cjCKELTNJTpaerZAphsYg@mail.gmail.com
State New
Headers show
Series [d] Committed refactor building typeof(null) value. | expand

Commit Message

Iain Buclaw Jan. 15, 2019, 11:03 p.m. UTC
Hi,

This patch moves into one function building the typeof(null) values in
the D front-end.

Bootstrapped and regression tested on x86_64-linux-gnu.

Committed to trunk as r267955.
diff mbox series

Patch

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index e62d1f9d3b3..7ca0acffcc4 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -448,6 +448,42 @@  extract_from_method_call (tree t, tree& callee, tree& object)
   callee = CONSTRUCTOR_ELT (t, 1)->value;
 }
 
+/* Build a typeof(null) constant of type TYPE.  Handles certain special case
+   conversions, where the underlying type is an aggregate with a nullable
+   interior pointer.  */
+
+tree
+build_typeof_null_value (Type *type)
+{
+  Type *tb = type->toBasetype ();
+  tree value;
+
+  /* For dynamic arrays, set length and pointer fields to zero.  */
+  if (tb->ty == Tarray)
+    value = d_array_value (build_ctype (type), size_int (0), null_pointer_node);
+
+  /* For associative arrays, set the pointer field to null.  */
+  else if (tb->ty == Taarray)
+    {
+      tree ctype = build_ctype (type);
+      gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype));
+
+      value = build_constructor_single (ctype, TYPE_FIELDS (ctype),
+					null_pointer_node);
+    }
+
+  /* For delegates, set the frame and function pointer fields to null.  */
+  else if (tb->ty == Tdelegate)
+    value = build_delegate_cst (null_pointer_node, null_pointer_node, type);
+
+  /* Simple zero constant for all other types.  */
+  else
+    value = build_zero_cst (build_ctype (type));
+
+  TREE_CONSTANT (value) = 1;
+  return value;
+}
+
 /* Build a dereference into the virtual table for OBJECT to retrieve
    a function pointer of type FNTYPE at position INDEX.  */
 
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 0f3cb7ad0c5..e9aa457d852 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -560,18 +560,12 @@  convert_expr (tree exp, Type *etype, Type *totype)
 
     case Tnull:
       /* Casting from typeof(null) is represented as all zeros.  */
-      if (tbtype->ty == Tarray)
-	{
-	  tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
-	  return d_array_value (build_ctype (totype), size_int (0),
-				build_nop (ptrtype, exp));
-	}
-      else if (tbtype->ty == Taarray)
-	return build_constructor (build_ctype (totype), NULL);
-      else if (tbtype->ty == Tdelegate)
-	return build_delegate_cst (exp, null_pointer_node, totype);
+      result = build_typeof_null_value (totype);
 
-      return build_zero_cst (build_ctype (totype));
+      /* Make sure the expression is still evaluated if necessary.  */
+      if (TREE_SIDE_EFFECTS (exp))
+	result = compound_expr (exp, result);
+      break;
 
     case Tvector:
       if (tbtype->ty == Tsarray)
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index adab1d1f892..6ffb0f32a1f 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -511,6 +511,7 @@  extern tree delegate_object (tree);
 extern tree build_delegate_cst (tree, tree, Type *);
 extern tree build_method_call (tree, tree, Type *);
 extern void extract_from_method_call (tree, tree &, tree &);
+extern tree build_typeof_null_value (Type *);
 extern tree build_vindex_ref (tree, tree, size_t);
 extern tree d_save_expr (tree);
 extern tree stabilize_expr (tree *);
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index fecdffde020..15754a1dc2e 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2941,33 +2941,7 @@  public:
 
   void visit (NullExp *e)
   {
-    Type *tb = e->type->toBasetype ();
-    tree value;
-
-    /* Handle certain special case conversions, where the underlying type is an
-       aggregate with a nullable interior pointer.  */
-    if (tb->ty == Tarray)
-      {
-	/* For dynamic arrays, set length and pointer fields to zero.  */
-	value = d_array_value (build_ctype (e->type), size_int (0),
-			       null_pointer_node);
-      }
-    else if (tb->ty == Taarray)
-      {
-	/* For associative arrays, set the pointer field to null.  */
-	value = build_constructor (build_ctype (e->type), NULL);
-      }
-    else if (tb->ty == Tdelegate)
-      {
-	/* For delegates, set the frame and function pointer to null.  */
-	value = build_delegate_cst (null_pointer_node,
-				    null_pointer_node, e->type);
-      }
-    else
-      value = d_convert (build_ctype (e->type), integer_zero_node);
-
-    TREE_CONSTANT (value) = 1;
-    this->result_ = value;
+    this->result_ = build_typeof_null_value (e->type);
   }
 
   /* Build a vector literal.  */