Commit 54d04de7 by Ian Lance Taylor

compiler: Check for negative or inverted arguments to make.

From-SVN: r194173
parent e9bfc606
...@@ -6623,7 +6623,7 @@ class Builtin_call_expression : public Call_expression ...@@ -6623,7 +6623,7 @@ class Builtin_call_expression : public Call_expression
lower_make(); lower_make();
bool bool
check_int_value(Expression*); check_int_value(Expression*, bool is_length);
// A pointer back to the general IR structure. This avoids a global // A pointer back to the general IR structure. This avoids a global
// variable, or passing it around everywhere. // variable, or passing it around everywhere.
...@@ -6897,11 +6897,8 @@ Builtin_call_expression::lower_make() ...@@ -6897,11 +6897,8 @@ Builtin_call_expression::lower_make()
else else
{ {
len_arg = *parg; len_arg = *parg;
if (!this->check_int_value(len_arg)) if (!this->check_int_value(len_arg, true))
{
this->report_error(_("bad size for make"));
return Expression::make_error(this->location()); return Expression::make_error(this->location());
}
if (len_arg->type()->integer_type() != NULL if (len_arg->type()->integer_type() != NULL
&& len_arg->type()->integer_type()->bits() > uintptr_bits) && len_arg->type()->integer_type()->bits() > uintptr_bits)
have_big_args = true; have_big_args = true;
...@@ -6912,11 +6909,23 @@ Builtin_call_expression::lower_make() ...@@ -6912,11 +6909,23 @@ Builtin_call_expression::lower_make()
if (is_slice && parg != args->end()) if (is_slice && parg != args->end())
{ {
cap_arg = *parg; cap_arg = *parg;
if (!this->check_int_value(cap_arg)) if (!this->check_int_value(cap_arg, false))
{ return Expression::make_error(this->location());
this->report_error(_("bad capacity when making slice"));
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()); return Expression::make_error(this->location());
} }
if (cap_arg->type()->integer_type() != NULL if (cap_arg->type()->integer_type() != NULL
&& cap_arg->type()->integer_type()->bits() > uintptr_bits) && cap_arg->type()->integer_type()->bits() > uintptr_bits)
have_big_args = true; have_big_args = true;
...@@ -6973,20 +6982,36 @@ Builtin_call_expression::lower_make() ...@@ -6973,20 +6982,36 @@ Builtin_call_expression::lower_make()
// function. // function.
bool 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; Numeric_constant nc;
mpz_t ival; if (e->numeric_constant_value(&nc))
if (e->numeric_constant_value(&nc) && nc.to_int(&ival))
{ {
mpz_clear(ival); unsigned long v;
switch (nc.to_unsigned_long(&v))
{
case Numeric_constant::NC_UL_VALID:
return true; 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; return false;
} }
......
...@@ -11,6 +11,7 @@ package main ...@@ -11,6 +11,7 @@ package main
var bug = false var bug = false
var minus1 = -1 var minus1 = -1
var five = 5
var big int64 = 10 | 1<<32 var big int64 = 10 | 1<<32
type block [1<<19]byte type block [1<<19]byte
...@@ -40,7 +41,7 @@ func badcap() { ...@@ -40,7 +41,7 @@ func badcap() {
} }
func badcap1() { func badcap1() {
g1 = make([]block, 10, 5) g1 = make([]block, 10, five)
} }
func bigcap() { func bigcap() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment