diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-09-21 17:48:30 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-09-21 17:48:30 +0000 |
commit | 211993b35244486d8b496344a94f1bd109b2e7d2 (patch) | |
tree | 62e004ec784224e59aaae5e4b46ebea79d45fd2b /gcc | |
parent | 7f0919843b3218d66300278ee169bf4707dd33ea (diff) | |
download | gcc-211993b35244486d8b496344a94f1bd109b2e7d2.zip gcc-211993b35244486d8b496344a94f1bd109b2e7d2.tar.gz gcc-211993b35244486d8b496344a94f1bd109b2e7d2.tar.bz2 |
compiler: len(<-c) is not a constant.
From-SVN: r191616
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 95 |
1 files changed, 47 insertions, 48 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index ea24849..922b7df 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6679,38 +6679,6 @@ Builtin_call_expression::do_set_recover_arg(Expression* arg) this->set_args(new_args); } -// A traversal class which looks for a call expression. - -class Find_call_expression : public Traverse -{ - public: - Find_call_expression() - : Traverse(traverse_expressions), - found_(false) - { } - - int - expression(Expression**); - - bool - found() - { return this->found_; } - - private: - bool found_; -}; - -int -Find_call_expression::expression(Expression** pexpr) -{ - if ((*pexpr)->call_expression() != NULL) - { - this->found_ = true; - return TRAVERSE_EXIT; - } - return TRAVERSE_CONTINUE; -} - // Lower a builtin call expression. This turns new and make into // specific expressions. We also convert to a constant if we can. @@ -6731,20 +6699,6 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, if (this->is_constant()) { - // We can only lower len and cap if there are no function calls - // in the arguments. Otherwise we have to make the call. - if (this->code_ == BUILTIN_LEN || this->code_ == BUILTIN_CAP) - { - Expression* arg = this->one_arg(); - if (arg != NULL && !arg->is_constant()) - { - Find_call_expression find_call; - Expression::traverse(&arg, &find_call); - if (find_call.found()) - return this; - } - } - Numeric_constant nc; if (this->numeric_constant_value(&nc)) return nc.expression(loc); @@ -7061,8 +7015,42 @@ Builtin_call_expression::one_arg() const return args->front(); } -// Return whether this is constant: len of a string, or len or cap of -// a fixed array, or unsafe.Sizeof, unsafe.Offsetof, unsafe.Alignof. +// A traversal class which looks for a call or receive expression. + +class Find_call_expression : public Traverse +{ + public: + Find_call_expression() + : Traverse(traverse_expressions), + found_(false) + { } + + int + expression(Expression**); + + bool + found() + { return this->found_; } + + private: + bool found_; +}; + +int +Find_call_expression::expression(Expression** pexpr) +{ + if ((*pexpr)->call_expression() != NULL + || (*pexpr)->receive_expression() != NULL) + { + this->found_ = true; + return TRAVERSE_EXIT; + } + return TRAVERSE_CONTINUE; +} + +// Return whether this is constant: len of a string constant, or len +// or cap of an array, or unsafe.Sizeof, unsafe.Offsetof, +// unsafe.Alignof. bool Builtin_call_expression::do_is_constant() const @@ -7085,6 +7073,17 @@ Builtin_call_expression::do_is_constant() const && !arg_type->points_to()->is_slice_type()) arg_type = arg_type->points_to(); + // The len and cap functions are only constant if there are no + // function calls or channel operations in the arguments. + // Otherwise we have to make the call. + if (!arg->is_constant()) + { + Find_call_expression find_call; + Expression::traverse(&arg, &find_call); + if (find_call.found()) + return false; + } + if (arg_type->array_type() != NULL && arg_type->array_type()->length() != NULL) return true; |