NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

toolchain/38543: Anonymous unions crash lint2



>Number:         38543
>Category:       toolchain
>Synopsis:       Anonymous unions crash lint2
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 29 20:10:00 +0000 2008
>Originator:     Valery Ushakov
>Release:        current as ot 2008-04-29
>Organization:
>Environment:
>Description:
As reported in toolchain/38542, now that libm/Makefile enabled lint (in
revision 1.83) VAX build fails in libm.

Lint complains about unexpected open bracket in complex designated
initializer in mathimpl.h, wrapped below for readability:

const union { long l[2]; double d; } cat3(__,name,x) = {
   .l[0] = cat3t(0x,x1,x2),
   .l[1] = cat3t(0x,x3,x4)
};

.memeber[index] syntax confuses lint.

One possible workaround would be to simplify the initializer to

  { .l = { [0] = ..., [1] = ... } };

but unfortunately that triggers another bug (lint dumps core).

What happens is that lint2 doesn't handle anonymous structs, unions
and enums in tyname.  lint2 crashes with:

Program received signal SIGSEGV, Segmentation fault.
0x0804f47f in tyname (buf=0xbfbfe2d0 " ", bufsiz=64, tp=0xbbb040c0)
    at /usr/src/tools/lint2/../../usr.bin/xlint/lint2/../common/tyname.c:140
140                     (void)snprintf(buf, bufsiz, "%s %s", s,
(gdb)

where

(gdb) p *tp
$260 = {t_tspec = UNION, t_const = 0, t_volatile = 0, t_vararg = 0,
  t_isenum = 0, t_proto = 0, t_istag = 0, t_istynam = 0, t_isuniqpos = 1,
  t_u = {_t_dim = 129, _t_tag = 0x81, _t_tynam = 0x81, _t_uniqpos = {
      p_line = 129, p_file = 1, p_uniq = 0}, _t_args = 0x81}, t_subt = 0x0}
(gdb) p tp->t_tspec

i.e. the union is anonymous (t_isuniqpos=1), but tyname() doesn't
check for that and always try to access t_tag with predictable effects.

Simple-minded patch below prevents the crash

Index: tyname.c
===================================================================
RCS file: /cvsroot/src/usr.bin/xlint/common/tyname.c,v
retrieving revision 1.6
diff -u --unified -r1.6 tyname.c
--- tyname.c    28 Apr 2008 20:24:15 -0000      1.6
+++ tyname.c    29 Apr 2008 19:56:23 -0000
@@ -131,7 +131,7 @@
 #ifdef t_enum
                    tp->t_enum->etag->s_name
 #else
-                   tp->t_tag->h_name
+                   tp->t_isuniqpos ? "" : tp->t_tag->h_name
 #endif
                    );
                break;
@@ -141,7 +141,7 @@
 #ifdef t_str
                    tp->t_str->stag->s_name
 #else
-                   tp->t_tag->h_name
+                   tp->t_isuniqpos ? "" : tp->t_tag->h_name
 #endif
                    );
                break;

but the error message it produces is obscure:

Lint pass2:
__S2x value declared inconsistently (union  != union )  n_sincos.c?(39)  ::  
n_tan.c?(38)

>How-To-Repeat:
Try building libm in current for VAX after applying the following patch
(intended as a workaround for toolchain/38542):

Index: mathimpl.h
===================================================================
RCS file: /cvsroot/src/lib/libm/noieee_src/mathimpl.h,v
retrieving revision 1.8
diff -u --unified -r1.8 mathimpl.h
--- mathimpl.h  8 Jul 2006 00:28:21 -0000       1.8
+++ mathimpl.h  29 Apr 2008 20:02:13 -0000
@@ -67,10 +67,10 @@
     */
 #ifdef _LIBM_DECLARE
 #  define vc(name, value, x1,x2,x3,x4, bexp, xval) \
-       const union { long l[2]; double d; } cat3(__,name,x) = { .l[0] = 
cat3t(0x,x1,x2), .l[1] = cat3t(0x,x3,x4)};
+       const union { long l[2]; double d; } cat3(__,name,x) = { .l = { [0] = 
cat3t(0x,x1,x2), [1] = cat3t(0x,x3,x4) } };
 #elif defined(_LIBM_STATIC)
 #  define vc(name, value, x1,x2,x3,x4, bexp, xval) \
-       static const union { long l[2]; double d; } cat3(__,name,x) = { .l[0] = 
cat3t(0x,x1,x2), .l[1] = cat3t(0x,x3,x4)};
+       static const union { long l[2]; double d; } cat3(__,name,x) = { .l = { 
[0] = cat3t(0x,x1,x2), [1] = cat3t(0x,x3,x4) } };
 #else
 #  define vc(name, value, x1,x2,x3,x4, bexp, xval) \
        extern union { long l[2]; double d; } cat3(__,name,x);


>Fix:



Home | Main Index | Thread Index | Old Index