This patch to the Go compiler lowers constant string comparisons at compile time rather than runtime. Not doing this led to a compiler crash on code like
var V = "a" > "b" because the compiler thinks that expressions involving only constants do not require any runtime initialization, but string comparison requires a function call. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian
diff -r 67d188db0c17 go/expressions.cc --- a/go/expressions.cc Wed Feb 15 23:15:01 2012 -0800 +++ b/go/expressions.cc Thu Feb 16 13:50:38 2012 -0800 @@ -5824,15 +5824,46 @@ } // String constant expressions. - if (op == OPERATOR_PLUS - && left->type()->is_string_type() - && right->type()->is_string_type()) + if (left->type()->is_string_type() && right->type()->is_string_type()) { std::string left_string; std::string right_string; if (left->string_constant_value(&left_string) && right->string_constant_value(&right_string)) - return Expression::make_string(left_string + right_string, location); + { + if (op == OPERATOR_PLUS) + return Expression::make_string(left_string + right_string, + location); + else if (is_comparison) + { + int cmp = left_string.compare(right_string); + bool r; + switch (op) + { + case OPERATOR_EQEQ: + r = cmp == 0; + break; + case OPERATOR_NOTEQ: + r = cmp != 0; + break; + case OPERATOR_LT: + r = cmp < 0; + break; + case OPERATOR_LE: + r = cmp <= 0; + break; + case OPERATOR_GT: + r = cmp > 0; + break; + case OPERATOR_GE: + r = cmp >= 0; + break; + default: + go_unreachable(); + } + return Expression::make_boolean(r, location); + } + } } // Special case for shift of a floating point constant.