Browse Source

Fix misparsed type in presence of attributes

The type within the cast (int (__attribute__((foo)) *)(void))
was misparsed because of the presence of the attribute (parse_btype
prematurely concluded that (__attribute__() *) is a type.

Also see testcase.  This construct is used in sqlite it seems.
Michael Matz 1 year ago
parent
commit
22420ee1ee
3 changed files with 25 additions and 2 deletions
  1. 1 1
      tccgen.c
  2. 22 1
      tests/tests2/82_attribs_position.c
  3. 2 0
      tests/tests2/82_attribs_position.expect

+ 1 - 1
tccgen.c

@@ -4180,7 +4180,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
                 u = ad->attr_mode -1;
                 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
             }
-            break;
+            continue;
             /* GNUC typeof */
         case TOK_TYPEOF1:
         case TOK_TYPEOF2:

+ 22 - 1
tests/tests2/82_attribs_position.c

@@ -16,4 +16,25 @@ void __attribute__((stdcall)) foo (void)
 {
 }
 
-int main () { return 0; }
+/* The actual attribute isn't important, must just be
+   parsable.  */
+#define ATTR __attribute__((__noinline__))
+int ATTR actual_function() {
+  return 42;
+}
+
+extern int printf (const char *, ...);
+int main()
+{
+    void *function_pointer = &actual_function;
+
+    int a = ((ATTR int(*) (void)) function_pointer)();
+    printf("%i\n", a);
+
+    /* In the following we once misparsed 'ATTR *' is a btype
+       and hence the whole type was garbled.  */
+    int b = ( (int(ATTR *)(void))  function_pointer)();
+    printf("%i\n", b);
+
+    return 0;
+}

+ 2 - 0
tests/tests2/82_attribs_position.expect

@@ -0,0 +1,2 @@
+42
+42