2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+ PR c/17880
+ * c-typeck.c (digest_init): Call verify_sequence_points from here.
+ (c_finish_return): Likewise.
+ (c_start_case): Likewise.
+ * c-common.c (warn_for_collisions_1): Use explicit location in
+ warning.
+ * c-parser.c (c_parser_condition): New. Call
+ verify_sequence_points.
+ (c_parser_paren_condition): Call c_parser_condition.
+ (c_parser_for_statement): Call c_parser_condition.
+
+2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
PR 36901
* diagnostic.def (DK_PEDWARN, DK_PERMERROR): New.
* diagnostic.c (pedantic_warning_kind, permissive_error_kind):
&& DECL_NAME (list->expr))
{
warned_ids = new_tlist (warned_ids, written, NULL_TREE);
- warning (OPT_Wsequence_point, "operation on %qE may be undefined",
- list->expr);
+ warning_at (EXPR_HAS_LOCATION (writer)
+ ? EXPR_LOCATION (writer) : input_location,
+ OPT_Wsequence_point, "operation on %qE may be undefined",
+ list->expr);
}
list = list->next;
}
parser->in_if_block = in_if_block;
}
+/* Parse the condition from an if, do, while or for statements. */
+
+static tree
+c_parser_condition (c_parser *parser)
+{
+ location_t loc;
+ tree cond;
+ loc = c_parser_peek_token (parser)->location;
+ cond = c_objc_common_truthvalue_conversion
+ (c_parser_expression_conv (parser).value);
+ if (CAN_HAVE_LOCATION_P (cond))
+ SET_EXPR_LOCATION (cond, loc);
+ if (warn_sequence_point)
+ verify_sequence_points (cond);
+ return cond;
+}
+
/* Parse a parenthesized condition from an if, do or while statement.
condition:
static tree
c_parser_paren_condition (c_parser *parser)
{
- location_t loc;
tree cond;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
return error_mark_node;
- loc = c_parser_peek_token (parser)->location;
- cond = c_objc_common_truthvalue_conversion
- (c_parser_expression_conv (parser).value);
- if (CAN_HAVE_LOCATION_P (cond))
- SET_EXPR_LOCATION (cond, loc);
+ cond = c_parser_condition (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
return cond;
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
/* Parse the loop condition. */
- loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_consume_token (parser);
}
else
{
- tree ocond = c_parser_expression_conv (parser).value;
- cond = c_objc_common_truthvalue_conversion (ocond);
- if (CAN_HAVE_LOCATION_P (cond))
- SET_EXPR_LOCATION (cond, loc);
+ cond = c_parser_condition (parser);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
/* Parse the increment expression. */
}
}
+ if (warn_sequence_point)
+ verify_sequence_points (inside_init);
+
/* Any type can be initialized
from an expression of the same type, optionally with braces. */
}
retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
+
+ if (warn_sequence_point)
+ verify_sequence_points (retval);
}
ret_stmt = build_stmt (RETURN_EXPR, retval);
"converted to %<int%> in ISO C");
exp = default_conversion (exp);
+
+ if (warn_sequence_point)
+ verify_sequence_points (exp);
}
}
2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+ PR c/17880
+ * gcc.dg/sequence-pt-pr17880.c: New.
+
+2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
PR c++/12242
* g++.dg/warn/pr12242.C: New.
--- /dev/null
+/* PR 17880 */
+/* { dg-do compile } */
+/* { dg-options "-Wsequence-point" } */
+
+int
+foo (int x)
+{
+ unsigned int a;
+ int b;
+
+ b = (a += 5) > a; /* { dg-warning "undefined" "sequence point warning" } */
+ b = (a += 5) + a == 10; /* { dg-warning "undefined" "sequence point warning" } */
+ b = (a -= 5) > a; /* { dg-warning "undefined" "sequence point warning" } */
+ b = (a -= 5) + a == 10; /* { dg-warning "undefined" "sequence point warning" } */
+ b = a-- > a; /* { dg-warning "undefined" "sequence point warning" } */
+ b = a-- + a == 10; /* { dg-warning "undefined" "sequence point warning" } */
+ b = ++a > a; /* { dg-warning "undefined" "sequence point warning" } */
+ b = ++a + a == 10; /* { dg-warning "undefined" "sequence point warning" } */
+
+ if ((a += 5) > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if ((a += 5) + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if ((a -= 5) > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if ((a -= 5) + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if (a-- > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if (a-- + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if (++a > a) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ if (++a + a == 10) return -1; /* { dg-warning "undefined" "sequence point warning" } */
+ do {} while ((a += 5) > a); /* { dg-warning "undefined" "sequence point warning" } */
+ while ((a += 5) > a); /* { dg-warning "undefined" "sequence point warning" } */
+ for ((a += 5) > a;;); /* { dg-warning "undefined" "sequence point warning" } */
+ for (b = (a += 5) > a;;); /* { dg-warning "undefined" "sequence point warning" } */
+ for (; (a += 5) > a;); /* { dg-warning "undefined" "sequence point warning" } */
+ for (;; b = (a += 5) > a); /* { dg-warning "undefined" "sequence point warning" } */
+ for (;; a++ + a++); /* { dg-warning "undefined" "sequence point warning" } */
+ if (a) a++ - a--; /* { dg-warning "undefined" "sequence point warning" } */
+ ((a +=5) > a) ? a : b; /* { dg-warning "undefined" "sequence point warning" } */
+ return (a++ - a--); /* { dg-warning "undefined" "sequence point warning" } */
+}
+
+void bar (int i)
+{
+ int a = i++ - i++; /* { dg-warning "undefined" "sequence point warning" } */
+}
+
+void baz (int i)
+{
+ switch (i++ + i++) /* { dg-warning "undefined" "sequence point warning" } */
+ {
+ case 1:
+ i++ - i++; /* { dg-warning "undefined" "sequence point warning" } */
+ case 2:
+ break;
+ }
+}