aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorterra@gnome.org <terra@gnome.org>2004-08-05 18:49:13 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:02:37 -0700
commitf1270ebe48c3bd9c5e91283eeb04b07f9e9eab7a (patch)
treef8b9afbdad0c1534c86e228c404dc79052286bd5
parentde5ea81679660d0545968a602fcc9d01d4d076b5 (diff)
downloadsparse-dev-f1270ebe48c3bd9c5e91283eeb04b07f9e9eab7a.tar.gz
[PATCH] "signed unsigned", "short long", "double x : 4", "int y : 1 : 2"
Don't allow nonsensical type descriptions like signed unsigned x; short long x; double x : 4; int y : 1 : 2;
-rw-r--r--evaluate.c9
-rw-r--r--parse.c25
-rw-r--r--symbol.h9
3 files changed, 27 insertions, 16 deletions
diff --git a/evaluate.c b/evaluate.c
index d41ae2ad..bcd0493a 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -194,15 +194,6 @@ static int is_ptr_type(struct symbol *type)
return type->type == SYM_PTR || type->type == SYM_ARRAY || type->type == SYM_FN;
}
-static inline int is_int_type(struct symbol *type)
-{
- if (type->type == SYM_NODE)
- type = type->ctype.base_type;
- return (type->type == SYM_ENUM) ||
- (type->type == SYM_BITFIELD) ||
- type->ctype.base_type == &int_type;
-}
-
static inline int is_float_type(struct symbol *type)
{
if (type->type == SYM_NODE)
diff --git a/parse.c b/parse.c
index 085f0f0f..ca11bafd 100644
--- a/parse.c
+++ b/parse.c
@@ -392,7 +392,7 @@ static void apply_ctype(struct position pos, struct ctype *thistype, struct ctyp
if (mod) {
unsigned long old = ctype->modifiers;
- unsigned long extra = 0, dup;
+ unsigned long extra = 0, dup, conflict;
if (mod & old & MOD_LONG) {
extra = MOD_LONGLONG | MOD_LONG;
@@ -403,6 +403,15 @@ static void apply_ctype(struct position pos, struct ctype *thistype, struct ctyp
if (dup)
warn(pos, "Just how %sdo you want this type to be?",
modifier_string(dup));
+
+ conflict = !(~mod & ~old & (MOD_LONG | MOD_SHORT));
+ if (conflict)
+ warn(pos, "You cannot have both long and short modifiers.");
+
+ conflict = !(~mod & ~old & (MOD_SIGNED | MOD_UNSIGNED));
+ if (conflict)
+ warn(pos, "You cannot have both signed and unsigned modifiers.");
+
ctype->modifiers = old | mod | extra;
}
@@ -573,12 +582,14 @@ static struct token *direct_declarator(struct token *token, struct symbol **tree
continue;
}
if (token->special == ':') {
- struct symbol *bitfield;
- struct expression *expr;
- bitfield = indirect(token->pos, ctype, SYM_BITFIELD);
- token = conditional_expression(token->next, &expr);
- bitfield->fieldwidth = get_expression_value(expr);
- continue;
+ if (is_int_type (ctype->base_type)) {
+ struct symbol *bitfield = indirect(token->pos, ctype, SYM_BITFIELD);
+ struct expression *expr;
+ token = conditional_expression(token->next, &expr);
+ bitfield->fieldwidth = get_expression_value(expr);
+ } else
+ error(token->pos, "Invalid bitfield specifier for type %s.", show_typename (ctype->base_type));
+ break;
}
break;
}
diff --git a/symbol.h b/symbol.h
index 8f654723..8e88852c 100644
--- a/symbol.h
+++ b/symbol.h
@@ -225,4 +225,13 @@ extern void debug_symbol(struct symbol *);
extern void merge_type(struct symbol *sym, struct symbol *base_type);
extern void check_declaration(struct symbol *sym);
+static inline int is_int_type(struct symbol *type)
+{
+ if (type->type == SYM_NODE)
+ type = type->ctype.base_type;
+ return (type->type == SYM_ENUM) ||
+ (type->type == SYM_BITFIELD) ||
+ type->ctype.base_type == &int_type;
+}
+
#endif /* SEMANTIC_H */