Linus Torvalds wrote:
>
> On Sun, 14 Aug 2005, Oleg Nesterov wrote:
> >
> > Does this patch make any sense?
>
> Yes and no. As you noticed, the end result is that we talk about "struct
> atomic_t", which is obviously wrong - atomic_t isn't a struct, it's a
> typedef, and there is really no "strict atomic_t" type.
>
> So the old error message was in many ways more correct.

Yes.

The new patch tries to solve this, but I am very new to sparse,
so I can't understand all implications of adding MOD_TYPEDEF to
SYM_STRUCT->ctype.modifiers, and it looks ugly to me.

Also, I don't know how to test the changes. I see the validation/
dir, but I can't find anything like validation-test: in Makefile.

BTW, I see the small (harmless) inconsistency in sparse:

        typedef struct anything
        {
                int x;
        } type_t;

        type_t *ptr;

        ptr->x;

evaluate_member_dereference() will return member which has MOD_USERTYPE
in ->ctype.modifiers.

> Equally obviously, the new error message is a lot more _useful_, so I
> think your patch is fine despite resulting in that strangeness.
>
> It's not like you bind the identifier to NS_STRUCT, so it only affects
> error printout, it doesn't affect actual symbol binding (ie your change
> doesn't make "struct atomic_t" actually work in a program, as far as I can
> tell). But you should probably test that, and possibly add a note on the
> issue.

Yes, this ident still binded to NS_TYPEDEF namespace, see the test
code below, "struct atomic_t" won't work.

However, the old patch was wrong in that it could assign ->ident to
SYM_BASETYPE ctype. It is (I think) harmless, but of course incorrect.

If the new one is too ugly to be accepted, is there an alternative?
I am trying to make the application which tracks member dereference,
and it does not work in case of typedefed anonymous struct/union.

Ok, the new patch:

This patch tries to improve error messages for typedefed anonymous
structs.

Test code:

     1  typedef struct {
     2          int x;
     3  } T;
     4
     5  struct T {
     6          int y;
     7  };
     8
     9  static int tst(void)
    10  {
    11          T v_typedef;
    12          struct T v_struct;
    13
    14          v_typedef.x = 0;        // OK
    15          v_typedef.y = 0;        // TST.c:15:11: warning: no member 'y' 
in typedef struct T
    16
    17          v_struct.x = 0;         // TST.c:17:10: warning: no member 'x' 
in struct T
    18          v_struct.y = 0;         // OK
    19  }

Without this patch the 1-st warning was:
        TST.c:15:11: warning: no member 'y' in struct <unnamed>

Signed-off-by: Oleg Nesterov <[EMAIL PROTECTED]>

--- git-snapshot-20050814/symbol.h~1_typedef    2005-08-12 02:14:53.000000000 
+0400
+++ git-snapshot-20050814/symbol.h      2005-08-15 21:23:43.000000000 +0400
@@ -166,7 +166,7 @@ struct symbol {
 #define MOD_SPECIFIER  (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | 
MOD_SIGNEDNESS)
 #define MOD_SIZE       (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG)
 #define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE |     \
-       MOD_ASSIGNED | MOD_USERTYPE | MOD_FORCE | MOD_ACCESSED | 
MOD_EXPLICITLY_SIGNED)
+       MOD_ASSIGNED | MOD_USERTYPE | MOD_TYPEDEF | MOD_FORCE | MOD_ACCESSED | 
MOD_EXPLICITLY_SIGNED)
 
 
 /* Current parsing/evaluation function */
--- git-snapshot-20050814/parse.c~1_typedef     2005-08-12 02:14:53.000000000 
+0400
+++ git-snapshot-20050814/parse.c       2005-08-15 21:44:43.000000000 +0400
@@ -1699,7 +1699,20 @@ struct token *external_declaration(struc
        bind_symbol(decl, ident, is_typedef ? NS_TYPEDEF: NS_SYMBOL);
 
        base_type = decl->ctype.base_type;
-       if (!is_typedef && base_type && base_type->type == SYM_FN) {
+       if (!base_type)
+               /* Nothing to do */;
+       else if (is_typedef) {
+               if (!base_type->ident)
+                       switch (base_type->type) {
+                       case SYM_STRUCT:
+                       case SYM_UNION:
+                       case SYM_ENUM:
+                               base_type->ctype.modifiers |= MOD_TYPEDEF;
+                               base_type->ident = ident;
+                       default:
+                               ;
+                       }
+       } else if (base_type->type == SYM_FN) {
                /* K&R argument declaration? */
                if (lookup_type(token))
                        return parse_k_r_arguments(token, decl, list);
@@ -1708,7 +1721,7 @@ struct token *external_declaration(struc
 
                if (!(decl->ctype.modifiers & MOD_STATIC))
                        decl->ctype.modifiers |= MOD_EXTERN;
-       } else if (!is_typedef && base_type == &void_ctype && 
!(decl->ctype.modifiers & MOD_EXTERN)) {
+       } else if (base_type == &void_ctype && !(decl->ctype.modifiers & 
MOD_EXTERN)) {
                warning(token->pos, "void declaration");
        }
 
--- git-snapshot-20050814/evaluate.c~1_typedef  2005-08-12 02:14:53.000000000 
+0400
+++ git-snapshot-20050814/evaluate.c    2005-08-15 21:44:49.000000000 +0400
@@ -1595,13 +1595,16 @@ static struct symbol *evaluate_member_de
        if (!member) {
                const char *type = ctype->type == SYM_STRUCT ? "struct" : 
"union";
                const char *name = "<unnamed>";
+               const char *mods = "";
                int namelen = 9;
                if (ctype->ident) {
                        name = ctype->ident->name;
                        namelen = ctype->ident->len;
+                       if (ctype->ctype.modifiers & MOD_TYPEDEF)
+                               mods = "typedef ";
                }
-               warning(expr->pos, "no member '%s' in %s %.*s",
-                       show_ident(ident), type, namelen, name);
+               warning(expr->pos, "no member '%s' in %s%s %.*s",
+                       show_ident(ident), mods, type, namelen, name);
                return NULL;
        }
 
--- git-snapshot-20050814/show-parse.c~1_typedef        2005-08-12 
02:14:53.000000000 +0400
+++ git-snapshot-20050814/show-parse.c  2005-08-15 19:23:18.000000000 +0400
@@ -89,7 +89,7 @@ const char *modifier_string(unsigned lon
                "auto", "register", "static", "extern",
                "const", "volatile", "[signed]", "[unsigned]",
                "[char]", "[short]", "[long]", "[long]",
-               "[typdef]", "[structof]", "[unionof]", "[enum]",
+               "[typedef]", "[structof]", "[unionof]", "[enum]",
                "[typeof]", "[attribute]", "inline", "[addressable]",
                "[nocast]", "[noderef]", "[accessed]", "[toplevel]",
                "[label]", "[assigned]", "[type]", "[safe]",
-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to