Aharon Robbins <[email protected]>:

> TCC doesn't quite understand where const should and should not go. I'm
> getting this warning:
> 
> dfa.c:1795: warning: assignment discards qualifiers from pointer target type

Yes, there is a failure to follow this part of the C standard:

"If the specification of an array type includes any type qualifiers,
the element type is so-qualified, not the array type."

So things like this don't work:

typedef int A[1];
extern A const x;
extern const A x;

Both declarations of x should be equivalent to:

extern const int x[1];

On 2015-11-19 I committed a patch to handle some cases of this. Here's
a patch that might finish the job. Any comments, before I commit it?

Edmund
diff --git a/tccgen.c b/tccgen.c
index 0866281..ccc5c00 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3134,6 +3134,19 @@ ST_FUNC int is_btype_size(int bt)
   return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
 }
 
+static int parse_btype_modify(int t, CType *type, int mod)
+{
+    if (!(t & VT_ARRAY))
+        return t | mod;
+    if (type->ref->type.t & mod)
+        return t;
+    /* We have a case like "typedef int T[1]; T const x;".
+       We copy the referenced type so that we can safely modify it. */
+    type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
+    type->ref->type.t |= mod;
+    return t;
+}
+
 /* return 0 if no type declaration. otherwise, return the basic type
    and skip it. 
  */
@@ -3232,13 +3245,13 @@ static int parse_btype(CType *type, AttributeDef *ad)
         case TOK_CONST1:
         case TOK_CONST2:
         case TOK_CONST3:
-            t |= VT_CONSTANT;
+            t = parse_btype_modify(t, type, VT_CONSTANT);
             next();
             break;
         case TOK_VOLATILE1:
         case TOK_VOLATILE2:
         case TOK_VOLATILE3:
-            t |= VT_VOLATILE;
+            t = parse_btype_modify(t, type, VT_VOLATILE);
             next();
             break;
         case TOK_SIGNED1:
@@ -3309,18 +3322,22 @@ static int parse_btype(CType *type, AttributeDef *ad)
             s = sym_find(tok);
             if (!s || !(s->type.t & VT_TYPEDEF))
                 goto the_end;
-            t |= (s->type.t & ~VT_TYPEDEF);
-            if ((t & VT_ARRAY) &&
-                t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) {
-                /* This is a case like "typedef int T[1]; const T x;"
-                   in which which we must make a copy of the typedef
-                   type so that we can add the type qualifiers to it. */
-                type->ref = sym_push(SYM_FIELD, &s->type.ref->type,
-                                     0, s->type.ref->c);
-                type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE);
-            }
-            else
+            if (!(s->type.t & VT_ARRAY)) {
+                t |= (s->type.t & ~VT_TYPEDEF);
                 type->ref = s->type.ref;
+            } else {
+                if (t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) {
+                    /* This is a case like "typedef int T[1]; const T x;"
+                       in which which we must make a copy of the typedef
+                       type so that we can add the type qualifiers to it. */
+                    type->ref = sym_push(SYM_FIELD, &s->type.ref->type,
+                                         0, s->type.ref->c);
+                    type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE);
+                } else
+                    type->ref = s->type.ref;
+                t &= ~(VT_CONSTANT | VT_VOLATILE);
+                t |= (s->type.t & ~VT_TYPEDEF);
+            }
             if (s->r) {
                 /* get attributes from typedef */
                 if (0 == ad->a.aligned)
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to