The follows( ) function uses pa->os_lign when determining
whether an output section pa immediately follows another
section pb.
However, emits( ) was not using this alignment information
when laying out and padding the output sections. This seems
to be a bug.
I suspect that mach/arm/cv/cv.c might need a similar fix.
This should fix at least some instances of the "undefined
reference to `LLnc_recover'" error that happens in some
builds (https://github.com/davidgiven/ack/issues/218).
The bug was that genname( ) used a static `namebuf' buffer
and did not properly check for overflow when writing into
it. The result was that the `non_corr' variable was
sometimes overwritten with a non-zero value when it should
be zero, causing bogus results later.
This proposed patch makes genname( ) dynamically allocate
and resize a buffer for holding a target file name.
I also take this chance to fix a typo in correct_prefix().
The strength reduction (SR) phase mishandled the END pseudo when SR
found at least 2 different expressions in the same loop, and SR made a
new header for the loop.
Since 1987 (commit 159b84e), SR appended the new header to the end of
the procedure. Later, SR fixed the header by adding a BRA branch to
the loop's entry, and moving the END pseudo from the previous basic
block to the header. If SR found multiple expressions, it called
fix_header() multiple times, and tried to move the END again. The
extra move failed assert(INSTR(e) == ps_end), or moved another line
after the END, so opt2 (the peephole optimizer) would crash.
Fix by removing fix_header() and moving the code to make_header(), so
SR adds the BRA and moves the END when it makes the header, and does
so only once for each header.
Adjust init_code(), which inserts code into a header. Stop checking
for an empty header, because make_header() now adds BRA. After
inserting code before BRA, don't move LP_INSTR, because later
insertions should go before BRA, not after END.
Our build enables assertions in some other ACK tools (like assemblers
and LLgen), but disabled them in ego until now. Bug #203 becomes a
failed assertion in ego's SR phase:
sr: util/ego/sr/sr_reduce.c:483: fix_header: Assertion
`INSTR(e) == ps_end' failed.
Comment out 2 assertions in util/ego/share, because they fail on
systems with 4-byte int, 8-byte long.
Calls like `debug("something\n", 0, 0, 0, 0)` cause clang warnings,
because debug() is a macro that passes its arguments to printf(), and
clang warns about extra 0s to printf(). Silence the warnings by
hiding the printf() in a new function do_debug(). The code still
passes extra 0s to printf(), but clang can't warn.
Macros debug() and verbose() should use C99 __VA_ARGS__, so they don't
require the extra 0s; but ACK doesn't use __VA_ARGS__ yet.
Adjust some format strings for debug() or fatal(), or cast their
arguments, to match their types. I don't know whether uint32_t is
unsigned int or unsigned long, so I cast it to unsigned long, and
print it with "%lx".
In util/led/sym.c, #include "save.h" to declare savechar(), and use
parentheses to silence a clang warning in hash().
Most warnings are for functions implicitly returning int. Change most
of these functions to return void. (Traditional K&R C had no void
type, but C89 has it.)
Add prototypes to most function declarations in headers. This is
easy, because ego declares most of its extern functions, and the
comments listed most parameters. There were a few outdated or missing
declarations, and a few .c files that failed to include an .h with the
declarations.
Add prototypes to a few function definitions in .c files. Most
functions still have traditional K&R definitions. Most STATIC
functions still don't have prototypes, because they have no earlier
declaration where I would have added the prototype.
Change some prototypes in util/ego/share/alloc.h. Functions newmap()
and oldmap() handle an array of pointers to something; change the
array's type from `short **` to `void **`. Callers use casts to go
between `void **` and the correct type, like `line_p *`. Function
oldtable() takes a `short *`, not a `short **`; I added the wrong type
in 5bbbaf4.
Make a few other changes to silence warnings. There are a few places
where clang wants extra parentheses in the code.
Edit util/ego/ra/build.lua to add the missing dependency on ra*.h; I
needed this to prevent crashes from ra.
Fixes https://github.com/davidgiven/ack/issues/188
One call to n_coerc() omits the 6th and last argument. This worked in
traditional K&R C, but stops working if we declare n_coerc() with a
prototype of all 6 parameters.
Change the last parameter to a pointer. Declare n_coerc() with
prototype, so it now requires all 6 arguments. Pass NULL when have no
iocc_t. This NULL exists only to satisfy the prototype; n_coerc()
will not use this NULL.
A different fix would declare n_coerc() with 5 parameters and `...`,
then use <stdarg.h> to read the 6th argument when it exists.
Also add `static` and remove `register` in mach/proto/top/top.c. A
static function is only in one file, so its function declaration may
go in that file, instead of a header file.
Use the new syntax in the mips, pdp, powerpc tables to declare
functions before calling them. These declarations prevent compiler
warnings about implicitly declaring functions. They also provide
prototypes of the function parameters.
Also fix a warning in the powerpc table: use `bsearch(...) != NULL` to
avoid converting the pointer from bsearch() to an int.
The syntax for topgen is a block `{...}` among the parameters in the
top table. It looks like the syntax of LLgen, but topgen doesn't
allow nested blocks, so declarations like `struct whatever {...};`
don't work. The token OPEN_BRACKET that begins a declaration_block
doesn't conflict with the LETTER that begins a parameter_line or the
'%' that begins a separator.
Because a block writes a #line command to gen.h, a parameter line now
also writes a #line command to gen.h, so it doesn't get a wrong line
number from a previous block.
Use switch.h to reduce warnings from clang about implicit declarations
of functions. I used `grep ... do_*.c | sed ... | sort`, and some
manual editing, to make the big list of Do???() functions.
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
Use C89 size_t for sizes from sizeof() or to malloc() or realloc().
Remove obsolete (unsigned) casts. Sizes were unsigned int in
traditional C but are size_t in C89.
Silence some clang warnings. Add the second pair of round brackets in
`while ((ff = ff->ff_next))` to silence -Wparentheses. Change
`if (nc_first(...))/*nothing*/;` to `(void)nc_first(...);` to silence
-Wempty-body. The code in compute.c nc_first() had the form
`if (x) if (y) s; else t;`. The old indentation (before 10717cc)
suggests that the "else" belongs to the 2nd "if", so add braces like
`if (x) { if (y) s; else t; }` to silence -Wdangling-else.
Shuffle extern function declarations. Add missing declaration for
LLparse(). Stop declaring RENAME(); it doesn't exist. Move some
declarations from main.c to extern.h, so the C compiler may check that
the declarations are compatible with the function definitions.
Assume that standard C89 remove() is available and doesn't need the
UNLINK() wrapper.
In lib/incl, don't need to include <stdio.h> nor <stdlib.h> to use
assert().
Remove alloc.h. If you don't clean your build, then an outdated
BUILDDIR/obj/util/LLgen/headers/alloc.h will survive but should not
cause harm, because nothing includes it. Don't need to remove alloc.h
from util/LLgen/distr.sh, because it isn't there.
Run the bootstrap to rebuild LLgen.c, Lpars.c, tokens.c.
The ACK builds an internal LLgen without installing it. The new
target would rebuild LLgen's own parser using the ACK's internal
LLgen. Keep bootstrap.sh, which uses an installed LLgen. The new
target is more convenient for those who build the ACK but don't build
and install a separate LLgen.
This causes clang to give fewer warnings of implicit declarations of
functions.
In mach/pdp/cv/cv.c, rename wr_int2() to cv_int2() because it
conflicts with wr_int2() in <object.h>.
In util/ack, rename F_OK to F_TRANSFORM because it conflicts with F_OK
for access() in <unistd.h>.
+ Addition of function prototypes and include files.
+ Change function definitions to ANSI C style.
- Remove support for generating K&R code.
- Remove mkstemp and replace by tmpnam (more portable but less safe)
In many systems, malloc() can allocate outside the brk area. The
calculation with sbrk() misses those allocations. When LLgen or ncgg
reported the memory usage, the value was probably too low.
Add USEMALLOC and enable it by default. You can switch back to brk()
by removing `#define USEMALLOC` in memory.c.
USEMALLOC tells the allocator to use malloc() and realloc(), not
brk(). This might help systems where brk() doesn't work, or where
malloc() can allocate outside the brk area.
My build shows no changes in share/ack/examples (except hilo_bas.*).
Option -u was passing an offset from modulptr(0) in ALLOMODL to the
string in argv. If entername() would move ALLOMODL to make room in
ALLOGCHR, then the offset would become invalid, so the string would
get lost. This fix copies the string into ALLOMODL.
This was often not a problem because the initial size of ALLOGCHR in
mach.h is probably large enough for -u. This became a problem when I
caused the initial allocations to fail, and then only because the B
runtime uses -u.
Also move the declarations of `incore` and `core_alloc` to "memory.h".
Also correct SYMDEBUG to SYMDBUG. (I don't know if SYMDBUG works
because our build system never defines it.)
ind_t becomes an alias of size_t. ind_t becomes unsigned, so I edit
some code that was using negative ind_t. Some casts disappear, like
(long)sizeof(...) because the size is already a size_t. There are
changes to overflow checks. Callers with a size too big for size_t
must check it before calling the memory allocator. An overflow check
of BASE + incr in memory.c sbreak() now happens on all platforms, not
only when a pointer is smaller than a long.
My build shows no changes in share/ack/examples (except hilo_bas.*
changing with every build).
Remove some declarations (not all correct) and #include <errno.h>,
<time.h>, and <unistd.h> to get the correct declarations.
Disable mount(2), umount(2), and stime(2) because BSD (around
4.3BSD-Reno) lost compatibility with these Unix v7 functions.
em libmon vanished decades ago (or never existed), and also ass appears to have
a different idea of what the em opcodes are to everything else and gets
confused.