X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fgo%2Fgofrontend%2Ftypes.cc;h=9e64a6ac84a176d5614d9ab370a3be61796c1b9a;hp=03f1b3ea0c6efb488a4c24f80ed3f2dedfa5ea0b;hb=88b6c6b482354107ba74374327825742da01eecb;hpb=3ff2389b66099679e87ca136021735c6428a9922 diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 03f1b3ea0c6..9e64a6ac84a 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2230,15 +2230,13 @@ Type::is_backend_type_size_known(Gogo* gogo) return true; else { + Numeric_constant nc; + if (!at->length()->numeric_constant_value(&nc)) + return false; mpz_t ival; - mpz_init(ival); - Type* dummy; - bool length_known = at->length()->integer_constant_value(true, - ival, - &dummy); - mpz_clear(ival); - if (!length_known) + if (!nc.to_int(&ival)) return false; + mpz_clear(ival); return at->element_type()->is_backend_type_size_known(gogo); } } @@ -5106,17 +5104,22 @@ Array_type::is_identical(const Array_type* t, bool errors_are_identical) const // Try to determine the lengths. If we can't, assume the arrays // are not identical. bool ret = false; - mpz_t v1; - mpz_init(v1); - Type* type1; - mpz_t v2; - mpz_init(v2); - Type* type2; - if (l1->integer_constant_value(true, v1, &type1) - && l2->integer_constant_value(true, v2, &type2)) - ret = mpz_cmp(v1, v2) == 0; - mpz_clear(v1); - mpz_clear(v2); + Numeric_constant nc1, nc2; + if (l1->numeric_constant_value(&nc1) + && l2->numeric_constant_value(&nc2)) + { + mpz_t v1; + if (nc1.to_int(&v1)) + { + mpz_t v2; + if (nc2.to_int(&v2)) + { + ret = mpz_cmp(v1, v2) == 0; + mpz_clear(v2); + } + mpz_clear(v1); + } + } return ret; } @@ -5154,58 +5157,44 @@ Array_type::verify_length() return false; } - mpz_t val; - mpz_init(val); - Type* vt; - if (!this->length_->integer_constant_value(true, val, &vt)) + Numeric_constant nc; + if (!this->length_->numeric_constant_value(&nc)) { - mpfr_t fval; - mpfr_init(fval); - if (!this->length_->float_constant_value(fval, &vt)) - { - if (this->length_->type()->integer_type() != NULL - || this->length_->type()->float_type() != NULL) - error_at(this->length_->location(), - "array bound is not constant"); - else - error_at(this->length_->location(), - "array bound is not numeric"); - mpfr_clear(fval); - mpz_clear(val); - return false; - } - if (!mpfr_integer_p(fval)) - { - error_at(this->length_->location(), - "array bound truncated to integer"); - mpfr_clear(fval); - mpz_clear(val); - return false; - } - mpz_init(val); - mpfr_get_z(val, fval, GMP_RNDN); - mpfr_clear(fval); + if (this->length_->type()->integer_type() != NULL + || this->length_->type()->float_type() != NULL) + error_at(this->length_->location(), "array bound is not constant"); + else + error_at(this->length_->location(), "array bound is not numeric"); + return false; } - if (mpz_sgn(val) < 0) + unsigned long val; + switch (nc.to_unsigned_long(&val)) { + case Numeric_constant::NC_UL_VALID: + break; + case Numeric_constant::NC_UL_NOTINT: + error_at(this->length_->location(), "array bound truncated to integer"); + return false; + case Numeric_constant::NC_UL_NEGATIVE: error_at(this->length_->location(), "negative array bound"); - mpz_clear(val); return false; + case Numeric_constant::NC_UL_BIG: + error_at(this->length_->location(), "array bound overflows"); + return false; + default: + go_unreachable(); } Type* int_type = Type::lookup_integer_type("int"); - int tbits = int_type->integer_type()->bits(); - int vbits = mpz_sizeinbase(val, 2); - if (vbits + 1 > tbits) + unsigned int tbits = int_type->integer_type()->bits(); + if (sizeof(val) <= tbits * 8 + && val >> (tbits - 1) != 0) { error_at(this->length_->location(), "array bound overflows"); - mpz_clear(val); return false; } - mpz_clear(val); - return true; } @@ -5457,11 +5446,11 @@ Array_type::get_length_tree(Gogo* gogo) go_assert(this->length_ != NULL); if (this->length_tree_ == NULL_TREE) { + Numeric_constant nc; mpz_t val; - mpz_init(val); - Type* t; - if (this->length_->integer_constant_value(true, val, &t)) + if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val)) { + Type* t = nc.type(); if (t == NULL) t = Type::lookup_integer_type("int"); else if (t->is_abstract()) @@ -5472,8 +5461,6 @@ Array_type::get_length_tree(Gogo* gogo) } else { - mpz_clear(val); - // Make up a translation context for the array length // expression. FIXME: This won't work in general. Translate_context context(gogo, NULL, NULL, NULL); @@ -5824,23 +5811,17 @@ Array_type::do_reflection(Gogo* gogo, std::string* ret) const ret->push_back('['); if (this->length_ != NULL) { - mpz_t val; - mpz_init(val); - Type* type; - if (!this->length_->integer_constant_value(true, val, &type)) - error_at(this->length_->location(), - "array length must be integer constant expression"); - else if (mpz_cmp_si(val, 0) < 0) - error_at(this->length_->location(), "array length is negative"); - else if (mpz_cmp_ui(val, mpz_get_ui(val)) != 0) - error_at(this->length_->location(), "array length is too large"); + Numeric_constant nc; + unsigned long val; + if (!this->length_->numeric_constant_value(&nc) + || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID) + error_at(this->length_->location(), "invalid array length"); else { char buf[50]; - snprintf(buf, sizeof buf, "%lu", mpz_get_ui(val)); + snprintf(buf, sizeof buf, "%lu", val); ret->append(buf); } - mpz_clear(val); } ret->push_back(']'); @@ -5856,23 +5837,17 @@ Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const this->append_mangled_name(this->element_type_, gogo, ret); if (this->length_ != NULL) { - mpz_t val; - mpz_init(val); - Type* type; - if (!this->length_->integer_constant_value(true, val, &type)) - error_at(this->length_->location(), - "array length must be integer constant expression"); - else if (mpz_cmp_si(val, 0) < 0) - error_at(this->length_->location(), "array length is negative"); - else if (mpz_cmp_ui(val, mpz_get_ui(val)) != 0) - error_at(this->length_->location(), "array size is too large"); + Numeric_constant nc; + unsigned long val; + if (!this->length_->numeric_constant_value(&nc) + || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID) + error_at(this->length_->location(), "invalid array length"); else { char buf[50]; - snprintf(buf, sizeof buf, "%lu", mpz_get_ui(val)); + snprintf(buf, sizeof buf, "%lu", val); ret->append(buf); } - mpz_clear(val); } ret->push_back('e'); }