do_is_constant() const
{ return true; }
+ bool
+ do_is_zero_value() const
+ { return this->val_ == false; }
+
bool
do_is_static_initializer() const
{ return true; }
do_is_constant() const
{ return true; }
+ bool
+ do_is_zero_value() const
+ { return mpz_sgn(this->val_) == 0; }
+
bool
do_is_static_initializer() const
{ return true; }
do_is_constant() const
{ return true; }
+ bool
+ do_is_zero_value() const
+ {
+ return mpfr_zero_p(this->val_) != 0
+ && mpfr_signbit(this->val_) == 0;
+ }
+
bool
do_is_static_initializer() const
{ return true; }
do_is_constant() const
{ return true; }
+ bool
+ do_is_zero_value() const
+ {
+ return mpfr_zero_p(mpc_realref(this->val_)) != 0
+ && mpfr_signbit(mpc_realref(this->val_)) == 0
+ && mpfr_zero_p(mpc_imagref(this->val_)) != 0
+ && mpfr_signbit(mpc_imagref(this->val_)) == 0;
+ }
+
bool
do_is_static_initializer() const
{ return true; }
do_is_constant() const
{ return true; }
+ bool
+ do_is_zero_value() const
+ { return this->constant_->const_value()->expr()->is_zero_value(); }
+
bool
do_is_static_initializer() const
{ return true; }
do_is_constant() const
{ return true; }
+ bool
+ do_is_zero_value() const
+ { return true; }
+
bool
do_is_static_initializer() const
{ return true; }
return true;
}
+// Return whether a type conversion is a zero value.
+
+bool
+Type_conversion_expression::do_is_zero_value() const
+{
+ if (!this->expr_->is_zero_value())
+ return false;
+
+ // Some type conversion from zero value is still not zero value.
+ // For example, []byte("") or interface{}(0).
+ // Conservatively, only report true if the RHS is nil.
+ Type* type = this->type_;
+ if (type->integer_type() == NULL
+ && type->float_type() == NULL
+ && type->complex_type() == NULL
+ && !type->is_boolean_type()
+ && !type->is_string_type())
+ return this->expr_->is_nil_expression();
+
+ return true;
+}
+
// Return whether a type conversion can be used in a constant
// initializer.
return true;
}
+bool
+String_concat_expression::do_is_zero_value() const
+{
+ for (Expression_list::const_iterator pe = this->exprs_->begin();
+ pe != this->exprs_->end();
+ ++pe)
+ {
+ if (!(*pe)->is_zero_value())
+ return false;
+ }
+ return true;
+}
+
bool
String_concat_expression::do_is_static_initializer() const
{
return true;
}
+// Return whether this is a zero value.
+
+bool
+Struct_construction_expression::do_is_zero_value() const
+{
+ if (this->vals() == NULL)
+ return true;
+ for (Expression_list::const_iterator pv = this->vals()->begin();
+ pv != this->vals()->end();
+ ++pv)
+ if (*pv != NULL && !(*pv)->is_zero_value())
+ return false;
+
+ const Struct_field_list* fields = this->type_->struct_type()->fields();
+ for (Struct_field_list::const_iterator pf = fields->begin();
+ pf != fields->end();
+ ++pf)
+ {
+ // Interface conversion may cause a zero value being converted
+ // to a non-zero value, like interface{}(0). Be conservative.
+ if (pf->type()->interface_type() != NULL)
+ return false;
+ }
+
+ return true;
+}
+
// Return whether this struct can be used as a constant initializer.
bool
return true;
}
+// Return whether this is a zero value.
+
+bool
+Array_construction_expression::do_is_zero_value() const
+{
+ if (this->vals() == NULL)
+ return true;
+
+ // Interface conversion may cause a zero value being converted
+ // to a non-zero value, like interface{}(0). Be conservative.
+ if (this->type_->array_type()->element_type()->interface_type() != NULL)
+ return false;
+
+ for (Expression_list::const_iterator pv = this->vals()->begin();
+ pv != this->vals()->end();
+ ++pv)
+ if (*pv != NULL && !(*pv)->is_zero_value())
+ return false;
+
+ return true;
+}
+
// Return whether this can be used a constant initializer.
bool