This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gccgo] Handle len of a constant string expression
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 23 Dec 2009 22:40:15 -0800
- Subject: [gccgo] Handle len of a constant string expression
I committed this patch to the gccgo branch to correctly handle calling
the predeclared function len on a constant string expression. The
result is a constant; previously only a string constant was
recognized, not a string constant expression (e.g., "a" + "b"). The
patch includes a test case which is already committed upstream.
This fixes issue 337 in the Go issue tracker.
Ian
Index: gcc/testsuite/go.test/test/fixedbugs/bug237.go
===================================================================
--- gcc/testsuite/go.test/test/fixedbugs/bug237.go (revision 0)
+++ gcc/testsuite/go.test/test/fixedbugs/bug237.go (revision 0)
@@ -0,0 +1,25 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+var indent uint = 10
+func main() {
+ const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " +
+ ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
+ const n = uint(len(dots))
+ i := 2 * indent
+ var s string
+ for ; i > n; i -= n {
+ s += fmt.Sprint(dots)
+ }
+ s += dots[0:i]
+ if s != ". . . . . . . . . . " {
+ panic(s)
+ }
+}
Index: gcc/go/expressions.cc
===================================================================
--- gcc/go/expressions.cc (revision 155443)
+++ gcc/go/expressions.cc (working copy)
@@ -5263,14 +5263,15 @@ Builtin_call_expression::do_integer_cons
return false;
Type* arg_type = arg->type();
- if (this->code_ == BUILTIN_LEN
- && arg_type->is_string_type()
- && arg->classification() == EXPRESSION_STRING)
- {
- String_expression* se = static_cast<String_expression*>(arg);
- mpz_set_ui(val, se->val().length());
- *ptype = Type::lookup_integer_type("int");
- return true;
+ if (this->code_ == BUILTIN_LEN && arg_type->is_string_type())
+ {
+ std::string sval;
+ if (arg->string_constant_value(&sval))
+ {
+ mpz_set_ui(val, sval.length());
+ *ptype = Type::lookup_integer_type("int");
+ return true;
+ }
}
if (arg_type->points_to() != NULL