[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