diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-05 00:22:13 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-05 00:22:13 +0000 |
commit | 1ad00fd41a4aa99cd44f2ab4f3780a24448f2935 (patch) | |
tree | cbe1685ae7bb4bcb0b4607d751bd180d8c95a87b | |
parent | 21efa888a9ccce5048d252b6d422810119092f9e (diff) | |
download | gcc-1ad00fd41a4aa99cd44f2ab4f3780a24448f2935.tar.gz |
compiler: Check for negative or inverted arguments to make.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194173 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 61 | ||||
-rw-r--r-- | gcc/testsuite/go.test/test/fixedbugs/bug273.go | 3 |
2 files changed, 45 insertions, 19 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 7a5fcf27c95..3734d9b0b23 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6623,7 +6623,7 @@ class Builtin_call_expression : public Call_expression lower_make(); bool - check_int_value(Expression*); + check_int_value(Expression*, bool is_length); // A pointer back to the general IR structure. This avoids a global // variable, or passing it around everywhere. @@ -6897,11 +6897,8 @@ Builtin_call_expression::lower_make() else { len_arg = *parg; - if (!this->check_int_value(len_arg)) - { - this->report_error(_("bad size for make")); - return Expression::make_error(this->location()); - } + if (!this->check_int_value(len_arg, true)) + return Expression::make_error(this->location()); if (len_arg->type()->integer_type() != NULL && len_arg->type()->integer_type()->bits() > uintptr_bits) have_big_args = true; @@ -6912,11 +6909,23 @@ Builtin_call_expression::lower_make() if (is_slice && parg != args->end()) { cap_arg = *parg; - if (!this->check_int_value(cap_arg)) - { - this->report_error(_("bad capacity when making slice")); + if (!this->check_int_value(cap_arg, false)) + return Expression::make_error(this->location()); + + Numeric_constant nclen; + Numeric_constant nccap; + unsigned long vlen; + unsigned long vcap; + if (len_arg->numeric_constant_value(&nclen) + && cap_arg->numeric_constant_value(&nccap) + && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID + && nccap.to_unsigned_long(&vcap) == Numeric_constant::NC_UL_VALID + && vlen > vcap) + { + this->report_error(_("len larger than cap")); return Expression::make_error(this->location()); } + if (cap_arg->type()->integer_type() != NULL && cap_arg->type()->integer_type()->bits() > uintptr_bits) have_big_args = true; @@ -6973,20 +6982,36 @@ Builtin_call_expression::lower_make() // function. bool -Builtin_call_expression::check_int_value(Expression* e) +Builtin_call_expression::check_int_value(Expression* e, bool is_length) { - if (e->type()->integer_type() != NULL) - return true; - - // Check for a floating point constant with integer value. Numeric_constant nc; - mpz_t ival; - if (e->numeric_constant_value(&nc) && nc.to_int(&ival)) + if (e->numeric_constant_value(&nc)) { - mpz_clear(ival); - return true; + unsigned long v; + switch (nc.to_unsigned_long(&v)) + { + case Numeric_constant::NC_UL_VALID: + return true; + case Numeric_constant::NC_UL_NOTINT: + error_at(e->location(), "non-integer %s argument to make", + is_length ? "len" : "cap"); + return false; + case Numeric_constant::NC_UL_NEGATIVE: + error_at(e->location(), "negative %s argument to make", + is_length ? "len" : "cap"); + return false; + case Numeric_constant::NC_UL_BIG: + // We don't want to give a compile-time error for a 64-bit + // value on a 32-bit target. + return true; + } } + if (e->type()->integer_type() != NULL) + return true; + + error_at(e->location(), "non-integer %s argument to make", + is_length ? "len" : "cap"); return false; } diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug273.go b/gcc/testsuite/go.test/test/fixedbugs/bug273.go index c5e73e945c9..aabb912b913 100644 --- a/gcc/testsuite/go.test/test/fixedbugs/bug273.go +++ b/gcc/testsuite/go.test/test/fixedbugs/bug273.go @@ -11,6 +11,7 @@ package main var bug = false var minus1 = -1 +var five = 5 var big int64 = 10 | 1<<32 type block [1<<19]byte @@ -40,7 +41,7 @@ func badcap() { } func badcap1() { - g1 = make([]block, 10, 5) + g1 = make([]block, 10, five) } func bigcap() { |