[prev in list] [next in list] [prev in thread] [next in thread]
List: pcc-list
Subject: Re: function returning enum confusion
From: Otto Moerbeek <otto () drijf ! net>
Date: 2007-09-30 14:36:38
Message-ID: Pine.BSO.4.64.0709301632040.24204 () pepper ! intra ! drijf ! net
[Download RAW message or body]
On Wed, 26 Sep 2007, Otto Moerbeek wrote:
> Hi,
>
> This code gives a warning, which it should not. This might be related
> to the "#ifdef notdef" code in chkpun().
>
> -Otto
>
> [otto@pepper:40]$ pcc -c init004.c
> init004.c, line 9: warning: illegal pointer combination
> [otto@pepper:41]$
>
>
> enum foo {aap};
>
> enum foo eval_table(void);
>
> static const struct ops {
> enum foo (*afrunc)(void);
> } eval_ops[] = {
> { eval_table },
> };
more elaborate test case, not that the warnings produced when using -O
are not the same as without -O.
enum foo { bar };
enum footoo { bar1 };
enum foo f(void);
double g(void);
struct baz {
enum foo (*ff)(void);
};
struct baz a[] = { {f},
{g} };
static int h(enum foo *);
static int h(enum foo *arg)
{
return 0;
}
[otto@lou:51]$ pcc -O enum.c
init.c, line 11: warning: illegal pointer combination
init.c, line 12: warning: illegal pointer combination
init.c, line 17: warning: illegal pointer combination
Diff below to fix this and only come up with one legimate warning.
I ran this on the OpenBSD tree, and quite a few incorrect warnings
disappeared, and no false positives are reported. The actual check
done in chkenum() might need revisiting, I did not compare it letter
to letter with the standard.
-Otto
Index: trees.c
===================================================================
RCS file: /cvs/src/usr.bin/pcc/cc/ccom/trees.c,v
retrieving revision 1.3
diff -u -p -r1.3 trees.c
--- trees.c 16 Sep 2007 18:52:52 -0000 1.3
+++ trees.c 29 Sep 2007 20:29:59 -0000
@@ -72,6 +72,7 @@
# include <stdarg.h>
static void chkpun(NODE *p);
+static int chkenum(int, int, NODE *p);
static int opact(NODE *p);
static int moditype(TWORD);
static NODE *strargs(NODE *);
@@ -754,25 +755,15 @@ chkpun(NODE *p)
if (BTYPE(t2) == VOID && (t1 & TMASK))
return;
-#ifdef notdef
- /* C99 says that enums always should be handled as ints */
/* check for enumerations */
- if (t1==ENUMTY || t2==ENUMTY) {
- if( clogop( p->n_op ) && p->n_op != EQ && p->n_op != NE ) {
- werror( "comparison of enums" );
- return;
- }
- if (t1==ENUMTY && t2==ENUMTY) {
- if (p->n_left->n_sue!=p->n_right->n_sue)
- werror("enumeration type clash, "
- "operator %s", copst(p->n_op));
+ if (t1 == ENUMTY || t2 == ENUMTY) {
+ if (clogop(p->n_op) && p->n_op != EQ && p->n_op != NE) {
+ werror("comparison of enums");
return;
}
- if ((t1 == ENUMTY && t2 <= BTMASK) ||
- (t2 == ENUMTY && t1 <= BTMASK))
+ if (chkenum(t1, t2, p))
return;
}
-#endif
if (ISPTR(t1) || ISARY(t1))
q = p->n_right;
@@ -810,6 +801,9 @@ chkpun(NODE *p)
}
++d1;
++d2;
+ } else if (t1 == ENUMTY || t2 == ENUMTY) {
+ chkenum(t1, t2, p);
+ return;
} else
break;
t1 = DECREF(t1);
@@ -817,6 +811,22 @@ chkpun(NODE *p)
}
werror("illegal pointer combination");
}
+}
+
+static int
+chkenum(int t1, int t2, NODE *p)
+{
+ if (t1 == ENUMTY && t2 == ENUMTY) {
+ if (p->n_left->n_sue != p->n_right->n_sue)
+ werror("enumeration type clash, operator %s", copst(p->n_op));
+ return 1;
+ }
+ if ((t1 == ENUMTY && !(t2 >= CHAR && t2 <= UNSIGNED)) ||
+ (t2 == ENUMTY && !(t1 >= CHAR && t1 <= UNSIGNED))) {
+ werror("illegal combination of enum and non-integer type");
+ return 1;
+ }
+ return 0;
}
NODE *
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic