drh / lcc

The lcc retargetable ANSI C compiler
https://drh.github.io/lcc/
2.03k stars 441 forks source link

Preprocessor hangs on an example from the C standard #30

Open alexfru opened 8 years ago

alexfru commented 8 years ago
#define x    3
#define f(a) f(x * (a))
#undef  x
#define x    2
#define g    f
#define z    z[0]
#define h    g(~
#define m(a) a(w)
#define w    0,1
#define t(a) a

f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
         (f)^m(m);

/* expected: */
/*
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
*/

Reproducible with the preprocessor compiled with Open Watcom C/C++ 1.9, MinGW 4.8.2, my Smaller C and run on Windows 7 x64. Also reproducible with the preprocessor compiled with gcc 4.6.3 on Ubuntu 12.04LTS.

ksherlock commented 8 years ago

This seems to be fixed with the updated plan9 cpp (#26)

alexfru commented 8 years ago

@ksherlock There's more, unfortunately. The following two don't produce correct output even with your pull request #26.

#define x 3
#define f(a) f(x * (a))
#undef x
#define x 2
#define g f
#define z z[0]
#define h g(~
#define m(a) a(w)
#define w 0,1
#define t(a) a
#define p() int
#define q(x) x
#define r(x,y) x ## y
#define str(x) # x
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };

/* expected: */
/*
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };
*/
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
t(10,,), t(,11,), t(,,12), t(,,) };
/* expected: */
/*
int j[] = { 123, 45, 67, 89,
10, 11, 12, };
*/

is still broken.

alexfru commented 8 years ago

@ksherlock I think abandoning this preprocessor, which lcc's authors didn't even write and may have problems debugging/fixing, and instead going for ucpp may be a far better solution. I just integrated it into my Smaller C compiler. Haven't yet seen a problem with ucpp. The sample code from the C standard preprocesses correctly with it.