summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2015-12-07 02:51:00 +0800
committerTing-Wei Lan <lantw44@gmail.com>2015-12-07 02:51:00 +0800
commit762c59fd74b760aab11f0185f16189d05bae1feb (patch)
tree2d0d9424d04c803665d7965cc9b7f23357f2dbe2
parent9f1f1c719ced16636fa9e37d3cea5a9e782b72b6 (diff)
downloadcompiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.tar
compiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.tar.gz
compiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.tar.bz2
compiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.tar.lz
compiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.tar.xz
compiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.tar.zst
compiler2015-762c59fd74b760aab11f0185f16189d05bae1feb.zip
Handle constant expressions with integer division by zero
-rw-r--r--src/ast.h3
-rw-r--r--src/semantic-analysis.c13
2 files changed, 11 insertions, 5 deletions
diff --git a/src/ast.h b/src/ast.h
index 8af5c8c..cfbfda1 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -61,7 +61,8 @@ typedef enum CcmmcKindOpUnary_enum {
typedef enum CcmmcKindConst_enum {
CCMMC_KIND_CONST_INT,
CCMMC_KIND_CONST_FLOAT,
- CCMMC_KIND_CONST_STRING
+ CCMMC_KIND_CONST_STRING,
+ CCMMC_KIND_CONST_ERROR
} CcmmcKindConst;
typedef enum CcmmcKindStmt_enum {
diff --git a/src/semantic-analysis.c b/src/semantic-analysis.c
index 98e71bb..673c3b6 100644
--- a/src/semantic-analysis.c
+++ b/src/semantic-analysis.c
@@ -15,13 +15,15 @@
static CcmmcValueConst eval_const_expr(CcmmcAst *expr) {
- if (expr->type_node == CCMMC_AST_NODE_CONST_VALUE) {
+ if (expr->type_node == CCMMC_AST_NODE_CONST_VALUE)
return expr->value_const;
- }
assert(expr->type_node == CCMMC_AST_NODE_EXPR);
assert(expr->value_expr.kind == CCMMC_KIND_EXPR_BINARY_OP);
CcmmcValueConst left = eval_const_expr(expr->child);
CcmmcValueConst right = eval_const_expr(expr->child->right_sibling);
+ if (left.kind == CCMMC_KIND_CONST_ERROR ||
+ right.kind == CCMMC_KIND_CONST_ERROR)
+ return (CcmmcValueConst){ .kind = CCMMC_KIND_CONST_ERROR };
switch (expr->value_expr.op_binary) {
case CCMMC_KIND_OP_BINARY_ADD:
if (left.kind == CCMMC_KIND_CONST_INT) {
@@ -95,8 +97,7 @@ static CcmmcValueConst eval_const_expr(CcmmcAst *expr) {
if (right.const_int == 0) {
fprintf(stderr, ERROR("Integer division by zero."),
expr->line_number);
- // XXX: We should have an invalid type
- return (CcmmcValueConst){ .kind = CCMMC_KIND_CONST_STRING };
+ return (CcmmcValueConst){ .kind = CCMMC_KIND_CONST_ERROR };
}
return (CcmmcValueConst){ .kind = CCMMC_KIND_CONST_INT,
.const_int = left.const_int / right.const_int };
@@ -142,6 +143,10 @@ static size_t *get_array_size(CcmmcAst *id_array, size_t *array_dimension)
ERR_FATAL_CHECK(array_size, malloc);
for (dim = id_array->child; dim != NULL; dim = dim->right_sibling, dim_index++) {
CcmmcValueConst value = eval_const_expr(dim);
+ if (value.kind == CCMMC_KIND_CONST_ERROR) {
+ free(array_size);
+ return NULL;
+ }
if (value.kind != CCMMC_KIND_CONST_INT) {
fprintf(stderr, ERROR("Array subscript is not an integer."),
dim->line_number);