Skip to content

Commit 826ff0b

Browse files
nicstangelucvoo
authored andcommitted
constexpr: treat comparisons between types as integer constexpr
The expression parsing code builds an EXPR_COMPARE expression around two EXPR_TYPE expressions for __builtin_types_compatible_p(). The EXPR_TYPE expressions are tagged as being integer constant expressions in order to trick the generic comparison evaluation code into flagging the result as an integer constant expression again. Avoid this trickery by making evaluate_compare() unconditionally tag a comparison between types as an integer constant expression. Signed-off-by: Nicolai Stange <[email protected]> Signed-off-by: Luc Van Oostenryck <[email protected]>
1 parent b59499d commit 826ff0b

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

evaluate.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -1016,16 +1016,21 @@ static struct symbol *evaluate_compare(struct expression *expr)
10161016
struct symbol *ctype;
10171017
const char *typediff;
10181018

1019-
expr->flags = left->flags & right->flags & ~CEF_CONST_MASK;
1020-
expr->flags &= ~CEF_ADDR;
1021-
10221019
/* Type types? */
1023-
if (is_type_type(ltype) && is_type_type(rtype))
1020+
if (is_type_type(ltype) && is_type_type(rtype)) {
1021+
/*
1022+
* __builtin_types_compatible_p() yields an integer
1023+
* constant expression
1024+
*/
1025+
expr->flags = CEF_SET_ICE;
10241026
goto OK;
1027+
}
10251028

10261029
if (is_safe_type(left->ctype) || is_safe_type(right->ctype))
10271030
warning(expr->pos, "testing a 'safe expression'");
10281031

1032+
expr->flags = left->flags & right->flags & ~CEF_CONST_MASK & ~CEF_ADDR;
1033+
10291034
/* number on number */
10301035
if (lclass & rclass & TYPE_NUM) {
10311036
ctype = usual_conversions(expr->op, expr->left, expr->right,

expression.c

-3
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ static struct token *parse_type(struct token *token, struct expression **tree)
131131
{
132132
struct symbol *sym;
133133
*tree = alloc_expression(token->pos, EXPR_TYPE);
134-
(*tree)->flags = CEF_SET_ICE; /* sic */
135134
token = typename(token, &sym, NULL);
136135
if (sym->ident)
137136
sparse_error(token->pos,
@@ -459,8 +458,6 @@ struct token *primary_expression(struct token *token, struct expression **tree)
459458
}
460459
if (token->special == '[' && lookup_type(token->next)) {
461460
expr = alloc_expression(token->pos, EXPR_TYPE);
462-
/* sic */
463-
expr->flags = CEF_SET_ICE;
464461
token = typename(token->next, &expr->symbol, NULL);
465462
token = expect(token, ']', "in type expression");
466463
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
static int a[] = {[__builtin_types_compatible_p(int, int)] = 0};
2+
3+
/*
4+
* check-name: __builtin_types_compatible_p() constness verification.
5+
*
6+
* check-error-start
7+
* check-error-end
8+
*/

0 commit comments

Comments
 (0)