changeset 442:eff8bc296c57

Fix indirections with function pointers (***fn)() (grischka-2005-09-29 case_9) This fixes handling of indirections with function pointers. This patch was originally posted in grischka's 2005-09-25 email as required fix case_9 to compile gcc 2.95. David A. Wheeler modified the test case to fit into tcc's test framework. Wheeler removed printing the specific addresses of the functions, whch was in the original test case, because that breaks the test harness. After all, addresses assigned to functions will vary between compilers, versions of compilers, and in some configurations each run. Instead, the test case simply shows if the function pointer has the same address as the address of the function it's supposed to be pointing to, which is all that is required.
author Rob Landley <rob@landley.net>
date Sun, 06 May 2007 12:17:00 -0400
parents 6ed28bf1ff35
children 640e11dd53d7
files tcc.c tests/tcctest.c
diffstat 2 files changed, 20 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/tcc.c	Fri May 04 13:06:25 2007 -0400
+++ b/tcc.c	Sun May 06 12:17:00 2007 -0400
@@ -6280,13 +6280,17 @@
 /* indirection with full error checking and bound check */
 static void indir(void)
 {
-    if ((vtop->type.t & VT_BTYPE) != VT_PTR)
+    if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
+        if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
+            return;
         expect("pointer");
+    }
     if ((vtop->r & VT_LVAL) && !nocode_wanted)
         gv(RC_INT);
     vtop->type = *pointed_type(&vtop->type);
-    /* an array is never an lvalue */
-    if (!(vtop->type.t & VT_ARRAY)) {
+    /* Arrays and functions are never lvalues */
+    if (!(vtop->type.t & VT_ARRAY)
+        && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
         vtop->r |= lvalue_type(vtop->type.t);
         /* if bound checking, the referenced pointer must be checked */
         if (do_bounds_check) 
--- a/tests/tcctest.c	Fri May 04 13:06:25 2007 -0400
+++ b/tests/tcctest.c	Sun May 06 12:17:00 2007 -0400
@@ -1544,6 +1544,11 @@
         return fib(n-1) + fib(n-2);
 }
 
+int reply_self(int x)
+{
+    return x;
+}
+
 void funcptr_test()
 {
     void (*func)(int);
@@ -1567,6 +1572,14 @@
     printf("sizeof2 = %d\n", sizeof funcptr_test);
     printf("sizeof3 = %d\n", sizeof(&funcptr_test));
     printf("sizeof4 = %d\n", sizeof &funcptr_test);
+
+    /* Test function pointer indirection */
+    {
+        int (*pfn)(int) = reply_self;
+        printf("case_9: 1 (7,8) -> %d (%d,%d)\n",
+            (int) (reply_self == *pfn), pfn(7), (******pfn)(8));
+    }
+
 }
 
 void lloptest(long long a, long long b)