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