/* Right child of a ctf expression can be any type of unary exp. */
break; /* OK */
case NODE_TYPE_DECLARATOR:
- case NODE_ENUM:
/*
- * We are the length of a type declarator or the size of an enum
- * container. We can only be a numeric constant.
+ * We are the length of a type declarator.
*/
switch (node->u.unary_expression.type) {
case UNARY_SIGNED_CONSTANT:
case NODE_FLOATING_POINT:
case NODE_INTEGER:
case NODE_STRING:
+ case NODE_ENUM:
case NODE_STRUCT_OR_VARIANT_DECLARATION:
case NODE_VARIANT:
case NODE_STRUCT:
*/
if (!cds_list_empty(&node->u.type_declarator.pointers))
goto errperm;
- /* Fall-through */
- case NODE_TYPEDEF:
+ break; /* OK */
case NODE_TYPEALIAS_TARGET:
+ break; /* OK */
case NODE_TYPEALIAS_ALIAS:
+ /*
+ * Only accept alias name containing:
+ * - identifier
+ * - identifier * (any number of pointers)
+ * NOT accepting alias names containing [] (would otherwise
+ * cause semantic clash for later declarations of
+ * arrays/sequences of elements, where elements could be
+ * arrays/sequences themselves (if allowed in typealias).
+ * NOT accepting alias with identifier. The declarator should
+ * be either empty or contain pointer(s).
+ */
+ if (node->u.type_declarator.type == TYPEDEC_NESTED)
+ goto errperm;
+ if (cds_list_empty(&node->u.type_declarator.pointers))
+ goto errperm;
+ if (node->u.type_declarator.type == TYPEDEC_ID &&
+ node->u.type_declarator.u.id != NULL)
+ goto errperm;
+ break; /* OK */
+ case NODE_TYPEDEF:
case NODE_STRUCT_OR_VARIANT_DECLARATION:
break; /* OK */
case TYPEDEC_ID:
break;
case TYPEDEC_NESTED:
+ {
+ int nr_nest_len;
+
if (node->u.type_declarator.u.nested.type_declarator) {
ret = _ctf_visitor_semantic_check(fd, depth + 1,
node->u.type_declarator.u.nested.type_declarator);
if (ret)
return ret;
}
- if (node->u.type_declarator.u.nested.length) {
+ cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
+ siblings) {
ret = _ctf_visitor_semantic_check(fd, depth + 1,
- node->u.type_declarator.u.nested.length);
+ iter);
if (ret)
return ret;
+ nr_nest_len++;
+ if (iter->type == NODE_UNARY_EXPRESSION && nr_nest_len > 1) {
+ goto errperm;
+ }
}
if (node->u.type_declarator.bitfield_len) {
ret = _ctf_visitor_semantic_check(fd, depth + 1,
return ret;
}
break;
+ }
case TYPEDEC_UNKNOWN:
default:
fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__,
depth--;
break;
case NODE_TYPEALIAS_TARGET:
+ {
+ int nr_declarators;
+
switch (node->parent->type) {
case NODE_TYPEALIAS:
break; /* OK */
if (ret)
return ret;
}
+ nr_declarators = 0;
cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
if (ret)
return ret;
+ nr_declarators++;
+ }
+ if (nr_declarators > 1) {
+ fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
+
+ return -EINVAL;
}
depth--;
break;
+ }
case NODE_TYPEALIAS_ALIAS:
+ {
+ int nr_declarators;
+
switch (node->parent->type) {
case NODE_TYPEALIAS:
break; /* OK */
if (ret)
return ret;
}
+ nr_declarators = 0;
cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
if (ret)
return ret;
+ nr_declarators++;
+ }
+ if (nr_declarators > 1) {
+ fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
+
+ return -EINVAL;
}
depth--;
break;
+ }
case NODE_TYPEALIAS:
switch (node->parent->type) {
case NODE_ROOT:
}
depth++;
- if (node->u._enum.container_type) {
- ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u._enum.container_type);
+ cds_list_for_each_entry(iter, &node->u._enum.container_type,
+ siblings) {
+ ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
if (ret)
return ret;
}