Based on patch by Marc-André Lureau, fixes bug 606480.
var cleft = (CCodeExpression) expr.left.ccodenode;
var cright = (CCodeExpression) expr.right.ccodenode;
-
+
+ CCodeExpression? left_chain = null;
+ if (expr.chained) {
+ var lbe = (BinaryExpression) expr.left;
+
+ var temp_decl = get_temp_variable (lbe.right.value_type, true, null, false);
+ temp_vars.insert (0, temp_decl);
+ var cvar = get_variable_cexpression (temp_decl.name);
+ var ccomma = new CCodeCommaExpression ();
+ var clbe = (CCodeBinaryExpression) lbe.ccodenode;
+ if (lbe.chained) {
+ clbe = (CCodeBinaryExpression) clbe.right;
+ }
+ ccomma.append_expression (new CCodeAssignment (cvar, (CCodeExpression)lbe.right.ccodenode));
+ clbe.right = get_variable_cexpression (temp_decl.name);
+ ccomma.append_expression (cleft);
+ cleft = cvar;
+ left_chain = ccomma;
+ }
+
CCodeBinaryOperator op;
if (expr.operator == BinaryOperator.PLUS) {
op = CCodeBinaryOperator.PLUS;
}
expr.ccodenode = new CCodeBinaryExpression (op, cleft, cright);
+ if (left_chain != null) {
+ expr.ccodenode = new CCodeBinaryExpression (CCodeBinaryOperator.AND, left_chain, (CCodeExpression) expr.ccodenode);
+ }
}
public string? get_type_check_function (TypeSymbol type) {
}
}
+ public bool chained;
+
private Expression _left;
private Expression _right;
} else if (left.value_type is PointerType && right.value_type is PointerType) {
// pointer arithmetic
} else {
- var resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+ DataType resulting_type;
+
+ if (chained) {
+ var lbe = (BinaryExpression) left;
+ resulting_type = analyzer.get_arithmetic_result_type (lbe.right.value_type, right.value_type);
+ } else {
+ resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
+ }
if (resulting_type == null) {
error = true;
Expression parse_relational_expression () throws ParseError {
var begin = get_location ();
var left = parse_shift_expression ();
+
+ bool first = true;
bool found = true;
while (found) {
var operator = get_binary_operator (current ());
next ();
var right = parse_shift_expression ();
left = new BinaryExpression (operator, left, right, get_src (begin));
+ if (!first) {
+ var be = (BinaryExpression) left;
+ be.chained = true;
+ if (!context.experimental) {
+ Report.warning (left.source_reference, "chained relational expressions are experimental");
+ }
+ }
+ first = false;
break;
case BinaryOperator.GREATER_THAN:
next ();
if (current () != TokenType.OP_GT && current () != TokenType.OP_GE) {
var right = parse_shift_expression ();
left = new BinaryExpression (operator, left, right, get_src (begin));
+ if (!first) {
+ var be = (BinaryExpression) left;
+ be.chained = true;
+ if (!context.experimental) {
+ Report.warning (left.source_reference, "chained relational expressions are experimental");
+ }
+ }
+ first = false;
} else {
prev ();
found = false;