/* type specifiers */
#define MATCH_SPECIFIER(token, specifier, name) \
case token: \
- next_token(); \
if (type_specifiers & specifier) { \
errorf(HERE, "multiple " name " type specifiers given"); \
} else { \
type_specifiers |= specifier; \
} \
+ next_token(); \
break
MATCH_SPECIFIER(T__Bool, SPECIFIER_BOOL, "_Bool");
break;
case T_long:
- next_token();
if (type_specifiers & SPECIFIER_LONG_LONG) {
errorf(HERE, "multiple type specifiers given");
} else if (type_specifiers & SPECIFIER_LONG) {
} else {
type_specifiers |= SPECIFIER_LONG;
}
+ next_token();
break;
case T_struct: {
type1->compound.compound == type2->compound.compound;
}
+static expression_t const *get_reference_address(expression_t const *expr)
+{
+ bool regular_take_address = true;
+ for (;;) {
+ if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) {
+ expr = expr->unary.value;
+ } else {
+ regular_take_address = false;
+ }
+
+ if (expr->kind != EXPR_UNARY_DEREFERENCE)
+ break;
+
+ expr = expr->unary.value;
+ }
+
+ if (expr->kind != EXPR_REFERENCE)
+ return NULL;
+
+ /* special case for functions which are automatically converted to a
+ * pointer to function without an extra TAKE_ADDRESS operation */
+ if (!regular_take_address &&
+ expr->reference.entity->kind != ENTITY_FUNCTION) {
+ return NULL;
+ }
+
+ return expr;
+}
+
+static void warn_reference_address_as_bool(expression_t const* expr)
+{
+ if (!warning.address)
+ return;
+
+ expr = get_reference_address(expr);
+ if (expr != NULL) {
+ warningf(&expr->base.source_position,
+ "the address of '%Y' will always evaluate as 'true'",
+ expr->reference.entity->base.symbol);
+ }
+}
+
/**
* Parse a conditional expression, ie. 'expression ? ... : ...'.
*
conditional_expression_t *conditional = &result->conditional;
conditional->condition = expression;
+ warn_reference_address_as_bool(expression);
+
eat('?');
add_anchor_token(':');
"traditional C rejects the unary plus operator");
}
-static expression_t const *get_reference_address(expression_t const *expr)
-{
- bool regular_take_address = true;
- for (;;) {
- if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) {
- expr = expr->unary.value;
- } else {
- regular_take_address = false;
- }
-
- if (expr->kind != EXPR_UNARY_DEREFERENCE)
- break;
-
- expr = expr->unary.value;
- }
-
- /* special case for functions which are automatically converted to a
- * pointer to function without an extra TAKE_ADDRESS operation */
- if (!regular_take_address && expr->kind == EXPR_REFERENCE
- && expr->reference.entity->kind == ENTITY_FUNCTION) {
- return expr;
- }
-
- return NULL;
-}
-
-static void warn_function_address_as_bool(expression_t const* expr)
-{
- if (!warning.address)
- return;
-
- expr = get_reference_address(expr);
- if (expr != NULL) {
- warningf(&expr->base.source_position,
- "the address of '%Y' will always evaluate as 'true'",
- expr->reference.entity->base.symbol);
- }
-}
-
static void semantic_not(unary_expression_t *expression)
{
type_t *const orig_type = expression->value->base.type;
"operand of ! must be of scalar type");
}
- warn_function_address_as_bool(expression->value);
+ warn_reference_address_as_bool(expression->value);
expression->base.type = c_mode & _CXX ? type_bool : type_int;
}
type_t *const type_left = skip_typeref(orig_type_left);
type_t *const type_right = skip_typeref(orig_type_right);
- warn_function_address_as_bool(left);
- warn_function_address_as_bool(right);
+ warn_reference_address_as_bool(left);
+ warn_reference_address_as_bool(right);
if (!is_type_scalar(type_left) || !is_type_scalar(type_right)) {
/* TODO: improve error message */
add_anchor_token(')');
expression_t *const expr = parse_expression();
statement->ifs.condition = expr;
+ warn_reference_address_as_bool(expr);
mark_vars_read(expr, NULL);
rem_anchor_token(')');
expect(')');