ref: e1dec2bf0bdbd5b8f8cea993a48093bd411cd4ba
parent: 64122b83087c57a0fc5eb7a272816212f4994ab1
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Aug 6 07:43:18 EDT 2014
Make explicit checks of type in castings and sizeof The grammar we are using doesn't allow specify a function type name, but C standard allows it. This is a desviation from the standard, which is obvius wrong here. Accepting function types in typenames (or abstract declarators) make the grammar ambiguous because it is impossible difference between: (int (f)) -> function returning int with one parameter of type f (int (f)) -> integer variable f Function type names are stupid, because they are used as an alias of the function pointer types, but it makes stupid that something like sizeof(int (int)) is not allowed (because here should be understood as the size of a function), but it is allowed f(int (int)) because it is understood as a parameter with function pointer type. Although we don't allow function types names, we add checks against function types in sizeof and casting, becaues id adds documentation to the code and prepare it for the future.
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -305,6 +305,8 @@
{
if (!tp->defined)
error("invalid use of indefined type");
+ if (tp->op == FTN)
+ error("sizeof of a function");
return node(emitsizeof, inttype, TYP(tp), 0);
}
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -23,7 +23,7 @@
};
static struct dcldata *
-enqueue(struct dcldata *dp, uint8_t op, union dclunion u)
+queue(struct dcldata *dp, uint8_t op, union dclunion u)
{
if (dp->op == 255)
error("too much declarators");
@@ -32,14 +32,12 @@
return dp + 1;
}
-static struct dcldata *declarator0(struct dcldata *dp);
-
static struct dcldata *
arydcl(struct dcldata *dp)
{
expect('[');
expect(']');
- return enqueue(dp, ARY, (union dclunion) {.nelem = 0});
+ return queue(dp, ARY, (union dclunion) {.nelem = 0});
}
static Type *parameter(void);
@@ -79,7 +77,7 @@
ret:
expect(')');;
- return enqueue(dp, FTN, (union dclunion) {.pars = fp});
+ return queue(dp, FTN, (union dclunion) {.pars = fp});
}
static Symbol *
@@ -95,6 +93,8 @@
return sym;
}
+static struct dcldata *declarator0(struct dcldata *dp);
+
static struct dcldata *
directdcl(struct dcldata *dp)
{
@@ -108,7 +108,7 @@
sym = newiden();
else
sym = install("", NS_IDEN);
- dp = enqueue(dp, IDEN, (union dclunion) {.sym = sym});
+ dp = queue(dp, IDEN, (union dclunion) {.sym = sym});
}
for (;;) {
@@ -133,7 +133,7 @@
dp = directdcl(dp);
while (n--)
- dp = enqueue(dp, PTR, (union dclunion) {});
+ dp = queue(dp, PTR, (union dclunion) {});
return dp;
}
@@ -490,8 +490,6 @@
tp = specifier(&sclass);
if (sclass)
error("class storage in type name");
- if (yytoken == '(')
- error("type name specifies a function type");
sym = declarator(tp, ID_FORBIDDEN);
return sym->type;
}
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -551,13 +551,18 @@
case TQUALIFIER: case TYPE:
tp = typename();
expect(')');
- if (tp->op == ARY)
+ switch (tp->op) {
+ case ARY:
error("cast specify an array type");
- if ((np1 = eval(cast())) == NULL)
- unexpected();
- if ((np2 = convert(np1, tp, 1)) == NULL)
- error("bad type convertion requested");
- np2->b.lvalue = np1->b.lvalue;
+ case FTN:
+ error("cast specify a function type");
+ default:
+ if ((np1 = eval(cast())) == NULL)
+ unexpected();
+ if ((np2 = convert(np1, tp, 1)) == NULL)
+ error("bad type convertion requested");
+ np2->b.lvalue = np1->b.lvalue;
+ }
break;
default:
np2 = unary();