diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-09-30 03:45:27 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-09-30 03:45:27 +0200 |
commit | fded889cd4b3e0b5eef95440d3f96723e76a78e9 (patch) | |
tree | ded6cc96dae997390c6419e1f38e9be2a2fba07b | |
parent | 0ca5ee15e9836fca976479fef8d90594d1e97adb (diff) | |
parent | b8c706f3d0116b79f3935f36162fae610311c163 (diff) | |
download | sparse-fded889cd4b3e0b5eef95440d3f96723e76a78e9.tar.gz |
Merge branch 'relax-constexpr' into tip
-rw-r--r-- | evaluate.c | 28 | ||||
-rw-r--r-- | validation/constexpr-constcond.c | 10 | ||||
-rw-r--r-- | validation/ioc-typecheck.c | 4 |
3 files changed, 25 insertions, 17 deletions
@@ -1178,20 +1178,22 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr) expr->flags = (expr->conditional->flags & (*cond)->flags & expr->cond_false->flags & ~CEF_CONST_MASK); /* - * A conditional operator yields a particular constant - * expression type only if all of its three subexpressions are - * of that type [6.6(6), 6.6(8)]. - * As an extension, relax this restriction by allowing any - * constant expression type for the condition expression. - * - * A conditional operator never yields an address constant - * [6.6(9)]. - * However, as an extension, if the condition is any constant - * expression, and the true and false expressions are both - * address constants, mark the result as an address constant. + * In the standard, it is defined that an integer constant expression + * shall only have operands that are themselves constant [6.6(6)]. + * While this definition is very clear for expressions that need all + * their operands to be evaluated, for conditional expressions with a + * constant condition things are much less obvious. + * So, as an extension, do the same as GCC seems to do: + * Consider a conditional expression with a constant condition + * as having the same constantness as the argument corresponding + * to the truth value (including in the case of address constants + * which are defined more stricly [6.6(9)]). */ - if (expr->conditional->flags & (CEF_ACE | CEF_ADDR)) - expr->flags = (*cond)->flags & expr->cond_false->flags & ~CEF_CONST_MASK; + if (expr->conditional->flags & (CEF_ACE | CEF_ADDR)) { + int is_true = expr_truth_value(expr->conditional); + struct expression *arg = is_true ? *cond : expr->cond_false; + expr->flags = arg->flags & ~CEF_CONST_MASK; + } lclass = classify_type(ltype, <ype); rclass = classify_type(rtype, &rtype); diff --git a/validation/constexpr-constcond.c b/validation/constexpr-constcond.c new file mode 100644 index 00000000..d98da3dc --- /dev/null +++ b/validation/constexpr-constcond.c @@ -0,0 +1,10 @@ +extern int var; + +static int a[] = { + [0 ? var : 1] = 0, + [1 ? 2 : var] = 0, +}; + +/* + * check-name: constexprness in constant conditionals + */ diff --git a/validation/ioc-typecheck.c b/validation/ioc-typecheck.c index 34b37d31..7780773b 100644 --- a/validation/ioc-typecheck.c +++ b/validation/ioc-typecheck.c @@ -4,8 +4,4 @@ static unsigned iocnrs[] = { }; /* * check-name: integer constant & conditional expression - * check-known-to-fail - * - * check-error-start - * check-error-end */ |