return EXPR_CLASS_CONSTANT;
case INITIALIZER_VALUE:
- return is_constant_expression(initializer->value.value);
+ return is_linker_constant(initializer->value.value);
case INITIALIZER_LIST: {
expression_classification_t all = EXPR_CLASS_CONSTANT;
case EXPR_LABEL_ADDRESS:
return EXPR_CLASS_CONSTANT;
+ case EXPR_COMPOUND_LITERAL:
+ return is_constant_initializer(expression->compound_literal.initializer);
+
case EXPR_UNARY_TAKE_ADDRESS:
return is_object_with_linker_constant_address(expression->unary.value);
!(get_atomic_type_flags(dest->atomic.akind) & ATOMIC_TYPE_FLAG_INTEGER) ||
get_atomic_type_size(dest->atomic.akind) < get_type_size(type_void_ptr)
))
- return EXPR_CLASS_VARIABLE;
+ return is_constant_expression(expression);
- expression_classification_t const expr = is_constant_expression(expression->unary.value);
- expression_classification_t const addr = is_linker_constant(expression->unary.value);
- return expr > addr ? expr : addr;
+ return is_linker_constant(expression->unary.value);
}
case EXPR_BINARY_ADD:
} else if (!is_type_valid(ltype) || !is_type_valid(rtype)) {
return EXPR_CLASS_ERROR;
} else {
- return EXPR_CLASS_VARIABLE;
+ return is_constant_expression(expression);
}
}
skip_typeref(revert_automatic_type_conversion(expression));
if (!is_type_array(type))
return EXPR_CLASS_VARIABLE;
- expression_classification_t const ref = is_linker_constant(expression->array_access.array_ref);
- expression_classification_t const idx = is_constant_expression(expression->array_access.index);
- return ref < idx ? ref : idx;
+ return is_linker_constant(expression->array_access.array_ref);
}
case EXPR_CONDITIONAL: {
return EXPR_CLASS_VARIABLE;
}
- case EXPR_ERROR:
- return EXPR_CLASS_ERROR;
-
default:
- return EXPR_CLASS_VARIABLE;
+ return is_constant_expression(expression);
}
}
} expression_classification_t;
/**
- * Returns true if a given expression is a compile time
- * constant. ยง6.6
- *
- * @param expression the expression to check
+ * Returns true when an initializer contains only constants/linker_constant
+ * values.
*/
expression_classification_t is_constant_initializer(const initializer_t *initializer);
/**
* Checks if an expression is a constant/known value to the linker. Examples:
- * - all constant expression casted to a pointer type
+ * - all constant/linker constant expression casted to a pointer type
* - "&x", with x being a global variable.
* - "array" or "a.array" in case array is an array and array and a,
* respectively is an object with link time constant address
return result;
}
-/**
- * Checks if a given expression can be used as a constant initializer.
- */
-static bool is_initializer_constant(const expression_t *expression)
-{
- return is_constant_expression(expression) != EXPR_CLASS_VARIABLE ||
- is_linker_constant(expression) != EXPR_CLASS_VARIABLE;
-}
-
/**
* Parses an scalar initializer.
*
expression_t *expression = parse_assignment_expression();
mark_vars_read(expression, NULL);
- if (must_be_constant && !is_initializer_constant(expression)) {
+ if (must_be_constant && !is_linker_constant(expression)) {
errorf(&expression->base.source_position,
"initialisation expression '%E' is not constant",
expression);
expression_t *expression = parse_assignment_expression();
mark_vars_read(expression, NULL);
- if (env->must_be_constant && !is_initializer_constant(expression)) {
+ if (env->must_be_constant && !is_linker_constant(expression)) {
errorf(&expression->base.source_position,
"Initialisation expression '%E' is not constant",
expression);