tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] New fun bug! #include <regex.h>


From: Marc Andre Tanner
Subject: Re: [Tinycc-devel] New fun bug! #include <regex.h>
Date: Thu, 20 Sep 2007 23:00:33 +0200
User-agent: Mutt/1.5.16 (2007-06-11)

Hi,

[ Disclaimer: my C knowledge is fairly limited, so don't be surprised if
  not everything i am writing makes sense. ]

On Thu, Sep 06, 2007 at 06:08:49AM -0500, Rob Landley wrote:
> cat > blah.c << EOF
> #include <stdio.h>
> 
> #include <regex.h>
> 
> int main(int argc, char *argv[])
> {
>   return 0;
> }
> EOF
> tcc blah.c
> In file included from blah.c:3:
> /usr/include/regex.h:543: identifier expected
> 
> Which is:
> 
> > # if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) \
> >      && !defined __GNUG__
> > #  define __restrict_arr __restrict
> > # else
> > #  define __restrict_arr
> > # endif
> > #endif
> >
> > /* POSIX compatibility.  */
> > extern int regcomp (regex_t *__restrict __preg,
> >                     const char *__restrict __pattern,
> >                     int __cflags);
> >
> > extern int regexec (const regex_t *__restrict __preg,
> >                     const char *__restrict __string, size_t __nmatch,
> >                     regmatch_t __pmatch[__restrict_arr],
> ^ this line
> >                     int __eflags);
> 
> Which -E says becomes:
> 
> > extern int regexec ( const regex_t * __preg ,
> > const char * __string , size_t __nmatch ,
> > regmatch_t __pmatch [ restrict ] ,
> > int __eflags ) ;
> 
> And where did that "restrict" come from?  Earlier in the same file, of course:
> 
> > /* GCC 2.95 and later have "__restrict"; C99 compilers have
> >    "restrict", and "configure" may have defined "restrict".  */
> > #ifndef __restrict
> > # if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
> > #  if defined restrict || 199901L <= __STDC_VERSION__
> > #   define __restrict restrict
> > #  else
> > #   define __restrict
> > #  endif
> > # endif
> > #endif
>

__restrict and __restrict_arr are actually already defined and therefore
the ifndef's evaluate to false. I tracked it down and the definition
seems to come from here:

 regex.h => sys/types.h => features.h => sys/cdefs.h

Below is the relevant section from sys/cdefs.h

/* __restrict is known in EGCS 1.2 and above. */
#if !__GNUC_PREREQ (2,92)
# define __restrict     /* Ignore */
#endif

/* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is
     array_name[restrict]
   GCC 3.1 supports this.  */
#if __GNUC_PREREQ (3,1) && !defined __GNUG__
# define __restrict_arr __restrict
#else
# ifdef __GNUC__
#  define __restrict_arr        /* Not supported in old GCC.  */
# else
#  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#   define __restrict_arr       restrict
#  else
/* Some other non-C99 compiler.  */
#   define __restrict_arr       /* Not supported.  */
#  endif
# endif
#endif

And since recent tcc sets __STDC_VERSION__ to 199901L __restrict_arr is
defined as restrict which causes the problem because tcc doesn't know
how to handle this.

> I notice that the test here is 199901L <= __STDC_VERSION__ and the earlier 
> test was >=, and when they're == it gets _confused_...
> 
> I'm going to bed now.  Fixit in the morning...

Did you actually fix it? Because in todays tip the issue was still
present. Anyway i have attached my attempt to fix the problem, the patch
makes tcc ignore array definitions containing restrict as found in
regex.h. So the following should now be parseable without an error.

 extern int regexec ( const regex_t * __preg ,
                      const char * __string , size_t __nmatch ,
                      regmatch_t __pmatch [ restrict ] ,
                      int __eflags ) ;

During hacking, i found the following definitions in tcctok.h:

     DEF(TOK_RESTRICT1, "restrict")
     DEF(TOK_RESTRICT2, "__restrict")
     DEF(TOK_RESTRICT3, "__restrict__")

As i said before my C knowledge is quite limited, therefore i don't know 
which of the above variants are valid within the context of an array. My
patch handles currently only the first one which is enough to compile 
regex.h.

Don't know if it is the right way(tm) to fix the issue but it seems to
work for me, hope it doesn't break other stuff.

> Rob

Marc

-- 
 Marc Andre Tanner >< http://www.brain-dump.org/ >< GPG key: CF7D56C0

Attachment: restrict-array.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]