Commit Graph

901 Commits

Author SHA1 Message Date
Stephen Heumann d3aff49550 Use escape sequences in format strings printed by the format checker.
Error messages are now lined up to account for the actual printed length of any escape sequences.
2018-09-02 00:18:26 -05:00
Stephen Heumann 7493ffa76c Support the pause-on-errors feature for format checker messages. 2018-09-01 23:18:48 -05:00
Stephen Heumann ecff1e3479 Don't give an error when format string is not a string literal.
This may be indicative of dubious code in some cases, but it can also have valid use cases that are not easy to modify.

If desired, this could be re-enabled under a separate lint flag (analogous to -Wformat-nonliteral in GCC/Clang, which is available as an option but is not included in -Wformat or -Wall).
2018-09-01 22:36:31 -05:00
Stephen Heumann 94ec3c73c7 Various tweaks to printf/scanf format checking.
It is now stricter about invalid length modifiers. Also, "comp" is accepted where a floating-point type is expected (like the others, it is promoted to extended), and size specifiers are allowed with %n (now pretty much supported in the latest library version).
2018-09-01 22:25:38 -05:00
Stephen Heumann 69f086367c Adjust how messages from the printf/scanf format checker are displayed.
Mainly, this causes the messages from the format checker to be displayed after the relevant line is printed, along with any other error messages. The wording and formatting of some of the messages is also slightly adjusted, but there should be no substantive change in what is warned about.
2018-09-01 19:59:52 -05:00
Stephen Heumann 9ff3407c60 Avoid producing invalid string literals in #pragma expand output.
Previously, the characters ", /, and ? within string literals were not escaped in #pragma expand output, which could result in them being erroneously interpreted as ending the string literal, starting an escape sequence, or being part of a trigraph (respectively). Also, escape sequences were output in hexadecimal format. Since there is no length limit on hexadecimal escape sequences, this could result in subsequent characters in the string being interpreted as part of the escape sequence.

This fixes the issues by escaping the characters ", /, and ?, and by using three-digit octal escape sequences rather than hexadecimal ones.
2018-09-01 16:11:18 -05:00
Stephen Heumann a6f1211ee6 Properly treat #line directive as giving the next line number, not the current one. 2018-08-31 21:46:10 -05:00
Stephen Heumann 463da80902 Small tweaks to <stdarg.h>.
*Use a typedef rather than a macro definition for va_list. (The C standards specify that va_list is a type, although this would make a practical difference only if someone #undef'd it.)

*Don't include a semicolon in va_start(), so it expands to an expression rather than a statement. This could make a difference in a construct like "if (...) va_start(...); else ...".
2018-08-28 18:58:27 -05:00
Stephen Heumann 0b8d4ce3e4 Fix invalid static initialization of bitfields occupying three bytes.
An extra, fourth byte was being generated for the bitfield(s). This would cause all subsequent members of the struct and any enclosing object not to be initialized at the proper locations, which would generally corrupt their values.

The following program illustrates the issue:

#include <stdio.h>

struct X {
    int a:9;
    int b:9;
    int c;
} x = {123,234,12345};

int main(void) {
    printf("x.a = %i, x.b = %i, x.b = %i\n", x.a, x.b, x.c);
}
2018-04-11 23:42:04 -05:00
Stephen Heumann 0cfed00b52 Fix problem with static initialization of bitfields followed by non-bitfield members.
The initialized bytes for the bitfield(s) could wind up improperly being placed after those for the non-bitfield, generally corrupting both values.

The following program illustrates the problem:

#include <stdio.h>

struct X {
    int a:9;
    int b;
} x = {42,123};

int main(void) {
    printf("x.a = %i, x.b = %i\n", x.a, x.b);
}
2018-04-11 23:30:48 -05:00
Stephen Heumann 04b0143eff Update release notes to cover my recent changes.
printf/scanf format checking is not yet covered.
2018-04-10 23:36:18 -05:00
Stephen Heumann caabb5addf Allow declarations in first clause of for loop (C99). 2018-04-01 16:48:11 -05:00
Stephen Heumann 275e1f080b Add a new flag to control whether mixed declarations are allowed and C99 scope rules are used.
#pragma ignore bit 4 (a value of 16) now controls these. It is on by default (allowing them), but turning it off will restore the C89 rules.
2018-04-01 14:14:18 -05:00
Stephen Heumann 2be0ef0de5 Allow initialization of static/global variables with the address of members of const structs.
Note that this code currently permits discarding the const qualifier via such an initialization. That should give a diagnostic, but currently it doesn't in this or various other cases.

The following code (derived from a csmith-generated test case) illustrates the problem:

struct S0 {
   const long  f4;
};
const struct S0 g_149;
const long *g_311 = &g_149.f4;
2018-03-31 21:40:43 -05:00
Stephen Heumann a9f7f97a2f Avoid errors from attempting common subexpression elimination on the left subexpression of the comma operator.
This could happen because the left subexpression does not produce a result for use in the enclosing expression, and therefore is not of the form expected by the CSE code.

The following program (derived from a csmith-generated test case) illustrates the problem:

#pragma optimize 16
int main(void) {
    int i;
    i, (i, 1);
}
2018-03-31 20:10:50 -05:00
Stephen Heumann fd0ff033ad Fix code generation for certain cases where addresses are stored to local variables that don't fit in the direct page.
There was a bug when storing addresses generated by expressions like &a[i], where a is a global array and i is a variable. In certain cases where the destination location was a local variable that didn't fit in the direct page, the result of the address calculation would be stored to the wrong location on the stack. This failed to give the correct result, and could also sometimes cause crashes or other problems due to stack corruption.

The following program (derived from a csmith-generated test case) illustrates the issues:

#pragma optimize 1
long g_87[5];
static int g_242 = 4;

int main(void) {
    char l_298[256];
    long *l_284[3] = {0, 0, &g_87[g_242]};
    return l_284[2]-g_87; /* should be 4 */
}
2018-03-31 15:45:05 -05:00
Stephen Heumann bfe4416623 Fix some cases where decay of array types to pointer types was not handled correctly.
Specifically:
*The result of pointer arithmetic (or equivalent operations like &a[i]) always has pointer type.
*Array types decay to integer types in the context of comparison operations, so it is legal to compare two differently-sized arrays with the same element type.

The following program (partially derived from a csmith-generated test case) illustrates the issues:

int main(void) {
    int a[2], b[10];
    if (a == b) ; /* legal */
    if (&a[1] != &b[0]) ; /* legal */
    return sizeof(&b[1]); /* Should be sizeof(int*), i.e. 4 on GS */
}
2018-03-29 19:41:32 -05:00
Stephen Heumann 37cf771eee Fix bug where ++/-- operations would use the wrong location for local variables that don't fit in the direct page.
The code would trash other data on the stack, which could corrupt other variables and in some cases lead to crashes.

The following program (derived from a csmith-generated test case) shows the problem:

#pragma optimize -1
int main(void) {
    char arr[256] = {0};
    char l_565[3][2] = {{3,4}, {5,6}, {7,8}};
    l_565[0][0]++;
    return l_565[0][0];
}
2018-03-27 23:10:49 -05:00
Stephen Heumann 7605b7bbf2 Fix bug where bitwise binary ops on 32-bit values will be miscalculated and trash the stack in certain cases.
The following program (derived from a csmith-generated test case) demonstrates the crash:

#pragma optimize 8+64
#include <stdio.h>
long g = 0;
int main (void) {
    long l = 0x10305070;
    printf("%08lx\n", l ^ (g = (1 , 0x12345678)));
}
2018-03-27 20:11:45 -05:00
Kelvin Sherlock c2b24f2854 TermError doesn't always initalize the error message. commonly seen with compile +T. 2018-03-27 20:19:39 -04:00
Stephen Heumann 29de867039 Fix bug causing functions with 254 bytes of locals to crash on return.
This was a bug with the code for moving the return address. It would generate a "LDA 0" instruction when it was trying to load the value at DP+256.

The following program (derived from a csmith-generated test case) demonstrates the crash:

#pragma optimize 8
int main (int argc, char **argv) {
    char s[0xFC];
}
2018-03-26 23:30:26 -05:00
Stephen Heumann 21493271b9 Fix optimizer bug where tests of long or floating-point constants can trash the stack.
This problem could lead to crashes in code like the following (derived from a csmith-generated test case):

#pragma optimize 1
int main (void)
{
    if (1L) ;
}
2018-03-26 21:54:01 -05:00
Stephen Heumann f2d15b8fc7 Fix optimizer bug where casts with unused results could sometimes cause stack corruption.
This problem could lead to crashes in code like the following (derived from a csmith-generated test case):

#pragma optimize 1
static int main(void) {
    long i = 2;
    (long)(i > 1);
}
2018-03-26 19:57:18 -05:00
Stephen Heumann 7f94876fa8 Fix mis-optimization of "expression && non-zero constant" operations with 32-bit type.
The previous code may have been intended to convert this to a "!=0" test, which would have been valid if correctly implemented, but with the current code generator that actually yields worse code than the original version, so for now I just removed the optimization for this case.

This problem could lead to crashes in code like the following (derived from a csmith-generated test case):

#pragma optimize 1
int main(int argc, char *argv[]){
    long l_57 = argc;

    return (4 ^ l_57) && 6;
}
2018-03-26 18:30:45 -05:00
Stephen Heumann db98f7842d Fix mis-evaluation of certain equality comparisons with intermediate code optimization.
This affected comparisons of the form "logical operation or comparison == constant other than 0 or 1". These should always evaluate to 0 (false), but could mis-evaluate to true due to the bad optimization.

The following program gives an example showing the problem:

#pragma optimize 1
int main(void) {
        int i = 0, j = 42;
        return (i || j) == 123;
}
2018-03-26 18:20:36 -05:00
Stephen Heumann 7266b1d613 Properly support use of const structs and unions in assignments and as function arguments.
Here's an example that shows the issues (derived from a csmith-generated test case):

struct S {
   unsigned f;
};

void f1(struct S p) {
    printf("%u\n", p.f);
}

int main(void) {
    const struct S l = {123};
    struct S s;

    f1(l);

    s = l;
    printf("%u\n", s.f);
}
2018-03-25 20:56:15 -05:00
Stephen Heumann 4746d9ff60 Allow initialization of local vars with const-qualified struct or union type.
Here's an example that shows the problem (derived from a csmith-generated test case):

void f(void)
{
    const struct S {int i;} s = {1};
}
2018-03-25 18:22:37 -05:00
Stephen Heumann 9b08d4337a Prevent errors in loop invariant removal from trying to remove only the left subexpression of a comma operator.
Such subexpressions are not of the right form to work with the existing code, because they do not generate a value for use in the enclosing expression. For now, the code has been changed to simply not remove the subexpression in these cases. Alternative code could be written to make it work, but that might be more trouble than it's worth.

Here's an example that shows the problem (derived from a csmith-generated test case):

#pragma optimize 32+1 /* also had a problem with just 32 */
int main(void) {
    int x, y=10; /* also had problems if x was global */
    do {
        x=42, y-=1;
    } while (y);
    return x+y;
}
2018-03-25 18:22:37 -05:00
Stephen Heumann 237af41e90 Fix issue where a label with the same name as a typedef name was parsed as the beginning of a declaration.
This would lead to errors in programs like the following:

int main(void) {
        typedef int x;
x: ;
}

Even before support for mixed statements and declarations was introduced, this error could happen if the labeled statement was the first statement after the declarations in a block (as in the above example). Adding that support also allowed this error to happen with later statements in a block. The C4.2.4.1.CC test case was affected by this.
2018-03-25 18:22:37 -05:00
Stephen Heumann d6502c0719 Implement C99 scope rules for selection and iteration statements.
Under these rules, if, switch, for, while, and do statements each have their own block scopes separate from the enclosing scope, and their substatements also have their own block scopes.

This patch always applies the C99 scope rules, but a flag can be changed to disable them or make them conditional on a configuration setting.
2018-03-25 18:22:37 -05:00
Stephen Heumann 14adcd6a80 Allow mixed declarations and statements (C99). 2018-03-25 18:22:37 -05:00
MikeW50 24bf693985
Merge pull request #56 from ksherlock/printf_scanf
Add printf/scanf format checking [WIP]
2018-03-25 15:06:58 -06:00
MikeW50 e6c6d2d516
Merge pull request #52 from ksherlock/debugger-documentation
Debugger documentation
2018-03-25 15:06:39 -06:00
Kelvin Sherlock b9e6e4dd27 merge in updates from the ORCA Debugger disk. 2018-03-25 00:33:31 -04:00
ksherlock 7ef2ee2fcc Update Debugger.md
add updates after orca debugger was published.
2018-03-24 23:42:49 -04:00
ksherlock e69b437dc7 Update Debugger.md
name strings are stored in pascal format, not c format.
2018-03-24 23:42:49 -04:00
ksherlock a4e825198f Update Debugger.md
table format fixes
2018-03-24 23:42:49 -04:00
ksherlock e620357dc6 Create Debugger.md
from ORCA/Debugger appendix A, including mistakes.
2018-03-24 23:42:49 -04:00
Kelvin Sherlock 6c1ccc5c0d Squashed commit of the following:
commit 4265329097538640e9e21202f1b141bcd42a44f3
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Mar 23 21:45:32 2018 -0400

    indent to match standard indent.

commit 783518fbeb01d2df43ef2083d3341004c05e4e2e
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Mar 23 20:21:15 2018 -0400

    clean up the typenames

commit 29b627ecf5ca9b8a143761f85a1807a6ca35ddd9
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Mar 23 20:18:04 2018 -0400

    enable feature_hh, warn about %n with non-int modifier.

commit fc4ac8129e3772c4eda36658e344ec475938369c
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Mar 23 15:13:47 2018 -0400

    warn thar %lc, %ls, etc are unsupported.

commit 7e6b433ba0552f7e52f0f034d398e9195c764326
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Mar 23 13:36:25 2018 -0400

    warn about hh/ll modifier (if not supported)

commit 1943c9979d0013f9f38045ec04a962fbf0269f31
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Mar 23 11:42:41 2018 -0400

    use error facilities for format errors.

commit 7811168f56dca1387055574ba8d32638da2fad96
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Thu Mar 22 15:34:21 2018 -0400

    add feature flags to disable c99 enhancements until orca lib is updated.

commit c2149cc5953155cfc3c3b4d0483cd25fb946b055
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Thu Mar 22 08:59:10 2018 -0400

    Add printf/scanf format checking [WIP]

    This parses out the xprintf / xscanf format string and compares it with the function arguments.

    enabled via #pragma lint 16.
2018-03-23 21:51:27 -04:00
Stephen Heumann 5685009791 Update release notes to cover recent changes. 2018-03-17 22:54:53 -05:00
Stephen Heumann 324c979f3b Correctly handle tentative struct/union and array definitions that are not completed.
In the case of structs or unions, an error is now produced. This addresses one of the problems mentioned in issue #53.

In the case of arrays, tentative definitions like "int i[];" are now permitted at file scope. If not completed by a subsequent definition, this winds up producing an array with one element, initialized to 0. See the discussion and example in C99/C11 section 6.9.2 (or C90 section 6.7.2 and example in TC1).
2018-03-06 22:53:52 -06:00
Stephen Heumann c55acd1150 Give an error if the element type of an array type is an incomplete or function type. 2018-03-06 22:46:23 -06:00
Stephen Heumann 96f04b168e Do not enter forward-declared struct parameters in the global symbol table.
Memory for them is still allocated from the global pool, to ensure they remain available for as long as the function prototype that references them.

This addresses one of the problems mentioned in issue #53.
2018-03-06 19:46:51 -06:00
Stephen Heumann 78db036a85
Merge pull request #55 from ksherlock/debugger_struct_2
more nested struct type tweaks
2018-03-06 15:52:02 -06:00
Kelvin Sherlock ae55b80f2f Previous embedded struct debugger fix didn't account for pointers to structs (ExpandPointerType).
This always pre-increments symLength then compensate by subtracting 12 in GetTypeDisp.
2018-03-05 23:15:14 -05:00
Stephen Heumann cbdb773101 Add snprintf() and vsnprintf() prototypes in <stdio.h>. 2018-03-05 19:01:42 -06:00
Stephen Heumann ef30698ac8 Update <ctype.h> header to include isblank(), as both a macro and function.
In order to work right, this needs either GNO's ORCALib (which already included isblank()) or a copy of ORCA's ORCALib with the corresponding patch applied.
2018-03-05 18:59:25 -06:00
Stephen Heumann 28fa8b1853 Merge branch 'stack-repair-opt' 2018-03-04 16:09:08 -06:00
Stephen Heumann 0884c019d2 Generate correct debugger symbol tables for nested struct types.
Previously, when a struct type first appeared in a symbol table nested within another struct type, subsequent references to that type would use the wrong offset and be corrupted. This occurred because the symbol table length had not yet been updated to reflect the size of the entry for the outer structure at the time the inner one was processed.

Fixes #54.
2018-02-28 23:31:10 -06:00
Stephen Heumann 83df2fd9e1 Revert definition of FILE structure in <stdio.h> to match the implementation in ORCALib.
It had been changed to reflect changes in the ORCALib code that added a second putback buffer element, but those changes were problematic and have been reverted for now. (It's also not clear if ORCALib binaries with the larger putback buffer were ever distributed--at the least, they aren't on Opus ][ or in any of the ORCA/C 2.2.0 beta releases.)
2018-02-28 22:57:41 -06:00