Subject: C compiler bugs, cpp runs out of memory, yacc Index: src/lib/ccom/{c03,c11}.c src/lib/cpp/cpp.c src/usr.bin/yacc/{dextern,Makefile} Description: 1) Patch #490 fixed one bug in shifting of unsigned long but introduced a new bug when the '>>' operator is used with unsigned long. Typedefs declared multiple times cause an error. const/volatile must be allowed on both sides of a basic type 'const/volatile' referenced by indirection in structs caused the member to not be declared. 2) Patch #495 moved the ANSI C macros ___DATE___ and ___TIME___ from cc to cpp. ctime(3) causes cpp to run out of D space due to tables used by the timezone handling. 3) A yacc table is slightly undersized. This is unrelated to the bugs above but is included here to simplify installation of a future update. Repeat-By: 1) a) Recompile a kernel, notice that ARP (the function arpresolve()) is broken resulting in failure to communicate on the ethernet. This results from '>>' in the macro ARPTAB_HASH being miscompiled. b) Compile the following: extern int foo; extern int foo; typedef int bar; typedef int bar; x.c:4: bar redeclared c) Compile the following: struct buggy { int foo; }; struct buggy const bee; x.c:2: Type clash d) Compile the following: struct f { char *const *arg2; } bug; x(){ register char *const *p; p = bug.arg2; } x.c:3: arg2 undefined; func. x x.c:3: Illegal structure ref x.c:3: warning: mixed pointer assignment 2) Compile a kernel. Networking driver if_de.c is known to fail: # cc -O -DKERNEL -DMASTER -DINET -I. -I../h -DSUPERVISOR -S ../pdpif/if_de.c ../pdpif/if_de.c:1048: error: xmalloc: out of mem 3) A program ported to 2.11 required a slightly larger state table in yacc. Fix: 1) ragge@tethuvudet.se: "The logic in how I wrote it was correct, but I did make a mistake... I set nreg to 2 to tell there are only two registers available... But - when looking deeper into this it seems that c1 subtracts one from the value ... (which I missed)." "Allow for typedefs to be declared multiple times (in the same way as extern). This is a nice addition in c11 that can simplify headers significantly (no need for protection). "const/volatile must be allowed on both sides of a basic type but got an error if the type was a struct." 2) My suggestion was to call the external ctime() functions in /usr/libexec/ctimed. ragge@tethuvudet.se: "- Only call ctime() when __TIME__ or __DATE__ are referenced. - Lower vmf pages to 12. I noticed that the memory use was quite close to max when testing, so decreasing the number of vmf pages seemed reasonable. I also noticed that expanding the mbuf macros required many expansion buffers. I will revisit this sometimes." 3) The increase in MEMSIZE is offset by implementing shared strings using xstr(1) Cut where indicated and save to a file (/tmp/496.patch). Then: cd / patch -p0 < /tmp/496.patch cd /usr/src/lib/cpp make install make clean cd ../ccom make install make clean cd /usr/src/usr.bin/yacc make install make clean This and previous updates to 2.11BSD are available at the following locations: ftp://ftp.dfupdate.se/pub/pdp11/2.11BSD https://www.tuhs.org/Archive/Distributions/UCB/2.11BSD/Patches/ ftp://ftp.2bsd.com/2.11BSD http://www.2bsd.com/2.11BSD/ ---------------------------cut here-------------------- *** ./usr/src/lib/cpp/cpp.c.old Sun Aug 17 12:48:30 2025 --- ./usr/src/lib/cpp/cpp.c Fri Aug 29 20:35:55 2025 *************** *** 1,7 **** - /* $Id: cpp.c,v 1.311 2019/12/14 15:12:52 ragge Exp $ */ - #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)cpp.c 1.1 (2.11BSD) 2025/8/16"; #endif /* --- 1,5 ---- #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)cpp.c 1.2 (2.11BSD) 2025/8/29"; #endif /* *************** *** 90,95 **** --- 88,94 ---- char *Mxfile; int warnings, Mxlen, skpows; static usch utbuf[CPPBUF]; + static char timebuf[12], datebuf[14]; struct iobuf pb /* = { utbuf, 0, CPPBUF, 0, 1, BUTBUF } */ ; static void macstr(const usch *s); #if LIBVMF *************** *** 117,122 **** --- 116,123 ---- ino_t ino; } *incdir[2]; + static struct symtab *timloc; + static struct symtab *datloc; static struct symtab *filloc; static struct symtab *linloc; static struct symtab *pragloc; *************** *** 183,191 **** register int ch; register const usch *fn1, *fn2; char *a; - time_t t; - char timebuf[12], datebuf[12]; - char *timestring; #ifdef TIMING struct timeval t1, t2; --- 184,189 ---- *************** *** 193,201 **** (void)gettimeofday(&t1, NULL); #endif - timebuf[0] = '\0'; - datebuf[0] = '\0'; - #if LIBVMF if (vminit(NVMPGS)) error("vminit"); --- 191,196 ---- *************** *** 313,318 **** --- 308,320 ---- argc -= optind; argv += optind; + if (tflag == 0) { + datloc = lookup((const usch *)"__DATE__", ENTER); + timloc = lookup((const usch *)"__TIME__", ENTER); + timloc->type = TIMLOC; + datloc->type = DATLOC; + datloc->valoff = timloc->valoff = 1; + } filloc = lookup((const usch *)"__FILE__", ENTER); linloc = lookup((const usch *)"__LINE__", ENTER); pragloc = lookup((const usch *)"_Pragma", ENTER); *************** *** 346,360 **** if (tflag == 0) { - /* Create __TIME__ and __DATE__ as required by ANSI C */ - t = time(NULL); - timestring = ctime(&t); - /* ctime() string is a fixed size so we can "cheat" by using fixed offsets */ - strncat(timebuf, ×tring[11], 8); - strncat(datebuf, ×tring[4], 7); - strncat(datebuf, ×tring[20], 4); - bsheap(fb, "#define __DATE__ \"%s\"\n", datebuf); - bsheap(fb, "#define __TIME__ \"%s\"\n", timebuf); bsheap(fb, "#define __STDC__ 1\n"); bsheap(fb, "#define __STDC_VERSION__ 199901L\n"); } --- 348,353 ---- *************** *** 1799,1804 **** --- 1792,1815 ---- return 0; } + static void + inittime(void) + { + static int timeinited; + char *timestring; + time_t t; + + if (timeinited) + return; + /* Create __TIME__ and __DATE__ as required by ANSI C */ + t = time(NULL); + timestring = ctime(&t); + /* ctime() string is a fixed size so we can "cheat" by using fixed offsets */ + sprintf(timebuf, "\"%.8s\"", ×tring[11]); + sprintf(datebuf, "\"%.6s %.4s\"", ×tring[4], ×tring[20]); + timeinited = 1; + } + /* * Handle defined macro keywords found on input stream. * When finished print out the full expanded line. *************** *** 1826,1831 **** --- 1837,1850 ---- case LINLOC: return bsheap(NULL, "%d", ifiles->lineno); + case TIMLOC: + inittime(); + return bsheap(NULL, "%s", timebuf); + + case DATLOC: + inittime(); + return bsheap(NULL, "%s", datebuf); + case PRAGLOC: pragoper(NULL); return getobuf(BNORMAL); *************** *** 1922,1927 **** --- 1941,1954 ---- break; case LINLOC: ob = bsheap(NULL, "%d", ifiles->lineno); + break; + case TIMLOC: + inittime(); + ob = bsheap(NULL, "%s", timebuf); + break; + case DATLOC: + inittime(); + ob = bsheap(NULL, "%s", datebuf); break; case PRAGLOC: pragoper(ib); *** ./usr/src/lib/cpp/cpp.h.old Tue Jan 7 13:49:18 2020 --- ./usr/src/lib/cpp/cpp.h Fri Aug 29 20:36:19 2025 *************** *** 1,7 **** - /* $Id: cpp.h,v 1.113 2019/12/14 15:03:16 ragge Exp $ */ - #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)cpp.h 1.0 (2.11BSD) 2020/1/7"; #endif /* --- 1,5 ---- #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)cpp.h 1.1 (2.11BSD) 2025/8/29"; #endif /* *************** *** 75,82 **** #define PRAGLOC 3 /* _Pragma */ #define LINLOC 4 /* __LINE__ */ #define FILLOC 5 /* __FILE__ */ ! #define OBJCT 6 ! #define VARG 7 /* has varargs */ /* The following must be > MAXARGS since they are following WARN */ #define C99ARG 253 /* C99 vararg */ --- 73,82 ---- #define PRAGLOC 3 /* _Pragma */ #define LINLOC 4 /* __LINE__ */ #define FILLOC 5 /* __FILE__ */ ! #define TIMLOC 6 /* __TIME__ */ ! #define DATLOC 7 /* __DATE__ */ ! #define OBJCT 8 ! #define VARG 9 /* has varargs */ /* The following must be > MAXARGS since they are following WARN */ #define C99ARG 253 /* C99 vararg */ *** ./usr/src/lib/cpp/Makefile.old Sun Aug 10 13:32:13 2025 --- ./usr/src/lib/cpp/Makefile Fri Aug 29 20:35:16 2025 *************** *** 1,9 **** ! # Makefile 2.1 (2.11BSD) 2025/8/10 # # if machine has separate I/D SEPFLAG=-i ! VMPGS = 16 # else # LDFLAGS = # VMPGS = 4 --- 1,9 ---- ! # Makefile 2.2 (2.11BSD) 2025/8/29 # # if machine has separate I/D SEPFLAG=-i ! VMPGS = 12 # else # LDFLAGS = # VMPGS = 4 *************** *** 14,20 **** all : cpp cpp.0 cpp : cpp.o cpc.o token.o ! $(CC) $(CFLAGS) $(SEPFLAG) -o cpp cpp.o cpc.o token.o -lvmf cpp.0 : cpp.1 /usr/man/manroff cpp.1 > cpp.0 --- 14,20 ---- all : cpp cpp.0 cpp : cpp.o cpc.o token.o ! $(CC) $(CFLAGS) $(SEPFLAG) -o cpp cpp.o cpc.o token.o -lvmf -lstubs cpp.0 : cpp.1 /usr/man/manroff cpp.1 > cpp.0 *** ./usr/src/lib/ccom/c11.c.old Wed Apr 16 13:50:32 2025 --- ./usr/src/lib/ccom/c11.c Fri Aug 29 20:34:43 2025 *************** *** 3,9 **** */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)c11.c 2.2 (2.11BSD) 2025/4/16"; #endif #include "c1.h" --- 3,9 ---- */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)c11.c 2.3 (2.11BSD) 2025/8/29"; #endif #include "c1.h" *************** *** 988,994 **** else if (op==EXPR) { int onreg = nreg; if (gotrsh) ! nreg = 2; rcexpr(tp, efftab, 0); nreg = onreg; gotrsh = 0; --- 988,994 ---- else if (op==EXPR) { int onreg = nreg; if (gotrsh) ! nreg = 1; rcexpr(tp, efftab, 0); nreg = onreg; gotrsh = 0; *** ./usr/src/lib/ccom/c03.c.old Fri Jan 21 14:13:33 2022 --- ./usr/src/lib/ccom/c03.c Fri Aug 29 20:34:27 2025 *************** *** 6,12 **** */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)c03.c 2.1 (2.11BSD) 2022/1/21"; #endif #include "c0.h" --- 6,12 ---- */ #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)c03.c 2.2 (2.11BSD) 2025/8/29"; #endif #include "c0.h" *************** *** 178,184 **** if ((o=symbol())==NAME) { ssym = csym; mosflg = mosf; ! o = symbol(); if (o==LBRACE && ssym->hblklevhclass && ssym->hclass!=tagkind) { --- 178,186 ---- if ((o=symbol())==NAME) { ssym = csym; mosflg = mosf; ! do { ! o = symbol(); ! } while (o == KEYW && (cval == CONST || cval == VOLATIL)); if (o==LBRACE && ssym->hblklevhclass && ssym->hclass!=tagkind) { *************** *** 426,432 **** } if (!(dsym->hclass==0 || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1) ! || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type))) { redec(); goto syntax; } --- 428,435 ---- } if (!(dsym->hclass==0 || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1) ! || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type) ! || (skw==TYPEDEF && dsym->hclass==TYPEDEF && dsym->htype==type))) { redec(); goto syntax; } *************** *** 582,589 **** type = 0; more: switch(o=symbol()) { case KEYW: ! if (cval == CONST || cval == VOLATIL) goto more; break; case TIMES: --- 585,595 ---- type = 0; more: switch(o=symbol()) { case KEYW: ! if (cval == CONST || cval == VOLATIL) { ! mosflg = mossym; ! mossym = 0; goto more; + } break; case TIMES: *** ./usr/src/usr.bin/yacc/Makefile.old Thu Oct 24 13:33:58 1996 --- ./usr/src/usr.bin/yacc/Makefile Wed Aug 20 21:50:55 2025 *************** *** 1,24 **** # ! # @(#)Makefile 4.2.1 (2.11BSD) 1996/10/24 # DESTDIR= SEPFLAG= -i CFLAGS=-O ! SRCS = Makefile dextern files yaccpar \ ! y1.c y2.c y3.c y4.c \ ! yaccdiffs yaccnews all: yacc ! yacc: y1.o y2.o y3.o y4.o ! $(CC) ${SEPFLAG} -o yacc y?.o y1.o y2.o y3.o y4.o: dextern files install: yacc yaccpar ! install -s yacc $(DESTDIR)/usr/bin install -c yaccpar $(DESTDIR)/usr/share/misc clean : ! -rm -f *.o yacc ! ! srcs: $(SRCS) ! $(SRCS): ! sccs get $@ --- 1,30 ---- # ! # @(#)Makefile 4.3 (2.11BSD) 2025/8/20 # DESTDIR= SEPFLAG= -i CFLAGS=-O ! XSTR=xstr ! ! .c.o: ! cc -E ${CFLAGS} $*.c | ${XSTR} -c - ! cc ${CFLAGS} -c x.c ! mv x.o $*.o all: yacc ! yacc: y1.o y2.o y3.o y4.o strings.o ! $(CC) ${SEPFLAG} -o yacc y?.o strings.o ! y1.o y2.o y3.o y4.o: dextern files + + strings.o: strings + ${XSTR} + cc -c xs.c + mv xs.o strings.o + install: yacc yaccpar ! install -s -m 755 yacc $(DESTDIR)/usr/bin install -c yaccpar $(DESTDIR)/usr/share/misc clean : ! -rm -f *.o yacc x.c xs.c *** ./usr/src/usr.bin/yacc/dextern.old Fri Mar 13 03:31:06 1987 --- ./usr/src/usr.bin/yacc/dextern Fri Aug 29 20:38:48 2025 *************** *** 1,5 **** /* ! * @(#)dextern 4.2 (Berkeley) 3/21/86 */ # include # include --- 1,5 ---- /* ! * @(#)dextern 4.3 (2.11BSD) 2025/8/20 */ # include # include *************** *** 32,38 **** # ifdef MEDIUM # define ACTSIZE 4000 ! # define MEMSIZE 5200 # define NSTATES 600 # define NTERMS 127 # define NPROD 400 --- 32,38 ---- # ifdef MEDIUM # define ACTSIZE 4000 ! # define MEMSIZE 5400 # define NSTATES 600 # define NTERMS 127 # define NPROD 400 *** ./VERSION.old Mon Aug 18 08:06:44 2025 --- ./VERSION Fri Aug 29 19:35:23 2025 *************** *** 1,5 **** ! Current Patch Level: 495 ! Date: August 18, 2025 2.11 BSD ============ --- 1,5 ---- ! Current Patch Level: 496 ! Date: August 30, 2025 2.11 BSD ============