+2019-01-16 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * d-codegen.cc (build_typeof_null_value): New function.
+ * d-tree.h (build_typeof_null_value): Declare.
+ * d-convert.cc (convert_expr): Use build_typeof_null_value.
+ * expr.cc (ExprVisitor::visit(NullExp)): Likewise.
+
2019-01-15 Richard Sandiford <richard.sandiford@arm.com>
PR inline-asm/52813
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. */
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)
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 *);
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. */