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