Commit Graph

77 Commits

Author SHA1 Message Date
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
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
4a7644e0b5 Don't allocate stack space for varargs stack repair unless it's needed.
If there are no varargs calls (and nothing else that saves stack positions), then space doesn't need to be allocated for the saved stack position. This can also lead to more efficient prolog/epilog code for small functions.
2018-01-13 20:02:43 -06:00
Stephen Heumann
c588eda94e Allow a typedef'd version of "void" to be used in the parameter list of a function taking no arguments.
For example, the following is now allowed:
typedef void v;
void foo(v) {}

This appears to be permitted under at least C99 and C11 (the C89 wording is less clear), and is accepted by other modern compilers.
2017-10-21 20:36:21 -05:00
Stephen Heumann
f4ee840d9e Remove access to uninitialized variable.
There should be no functional change.

Issue reported by Kelvin Sherlock.
2017-10-21 20:36:21 -05:00
Stephen Heumann
e7cc513ad4 Add support for inline procedure names as documented in IIgs tech note #103.
These are enabled when bit 15 is set in the #pragma debug directive.

Support is still needed to ensure these work properly with pre-compiled headers.

This patch is from Kelvin Sherlock.
2017-10-21 20:36:21 -05:00
Stephen Heumann
5969d80e57 If 'volatile' is used within a function, only reduce optimization for that function.
Previously, several optimizations would be disabled for the rest of the translation unit whenever the keyword 'volatile' appeared. Now, if 'volatile' is used within a function, it only reduces optimization for that function, since whatever was declared as 'volatile' will be out of scope after the function is over. Uses of 'volatile' outside functions still behave as before.
2017-10-21 20:36:21 -05:00
Stephen Heumann
f79887c565 Don't erroneously pop the symbol table at declarations of a pointer to a typedef'd function type.
This problem could cause "duplicate symbol" and "undeclared identifier" errors, for example in the following program:

typedef int f1( void );
void bar( void ) {
    int i;
    f1 *foo;
    int baz;
    i = 10;
}
int foo;
long baz;
2017-10-21 20:36:21 -05:00
Stephen Heumann
5321ef2f84 Treat array types as compatible with corresponding pointer types in function prototypes.
This permits code like the following to compile, as it should:

int foo(int*);
int foo(int[]);
int foo(int[42]);
2017-10-21 20:36:21 -05:00
Stephen Heumann
227731a1a8 Allow "static inline" function declarations.
This should give C99-compatible behavior, as far as it goes. The functions aren't actually inlined, but that's just a quality-of-implementation issue. No C standard requires actual inlining.

Non-static inline functions are still not supported. The C99 semantics for them are more complicated, and they're less widely used, so they're a lower priority for now.

The "inline" function specifier can currently only come after the "static" storage class specifier. This relates to a broader issue where not all legal orderings of declaration specifiers are supported.

Since "inline" was already treated as a keyword in ORCA/C, this shouldn't create any extra compatibility issues for C89 code.
2017-10-21 20:36:21 -05:00
Stephen Heumann
db2a09bd1d Allow trailing comma in enum (as in C99).
Patch from Kelvin Sherlock.
2017-10-21 20:36:21 -05:00
Stephen Heumann
a75d18a45c Make the main function return 0 if execution reaches the closing brace of its body.
This is required by C99 and later. It’s not required by C89, but it’s allowed and produces more predictable behavior.
2017-10-21 20:36:21 -05:00
Stephen Heumann
f099222af6 Don't give an error when calling functions with const-qualified parameter types or returning from functions with const-qualified return type.
This fixes the compco12.c test case.
2017-10-21 20:36:21 -05:00
Stephen Heumann
b8c1ea753f Allow 'extern' storage-class specifier in function definitions.
Per the C standards, this is allowed and is equivalent to not specifying a storage-class specifier.
2017-10-21 20:36:21 -05:00
Stephen Heumann
45cc0a0721 Prevent struct/union members from having incomplete type, except for flexible array member.
ORCA/C previously allowed struct/union members to be declared with incomplete type. Because of this, it allowed C99-style flexible array members to be declared, albeit by accident rather than by design. In some basic testing, these seem to work correctly, except that they could be initialized and that would give rise to odd behavior.

I have restricted it to allowing flexible array members only in the cases allowed by C99/C11, and otherwise disallowing members with incomplete type. I have also prohibited initializing flexible array members.
2017-10-21 20:36:20 -05:00
Stephen Heumann
972b0109a4 Fix a problem where zero-initializing a one-byte array would crash the system.
Also, generate better code for zero-initializing small arrays.

The problem was that the code would call the library routine ~ZERO with a size of 1, but it only works properly with a size of 2 or more. While adding a check here, I also changed it to not call ~ZERO for other small arrays (<=10 bytes), since it is generally more efficient to just initialize them directly.

The initializations in the following are examples that could trigger the problem:

int main(void)
{
    struct { int i; char s[1]; } foo = {1, 0};
    char arr[2][1] = {2};
}
2017-10-21 20:36:20 -05:00
Stephen Heumann
b019c59803 Flag an error if a struct or enum field declaration contains no declarator (i.e. no name).
This may be someone trying to use a C11-style anonymous struct/union, which should be flagged as an error until and unless those are supported. Otherwise, it probably just indicates that the programmer is confused. In any case, an error should be flagged for it.
2017-10-21 20:36:20 -05:00
Stephen Heumann
1077c35a49 Restrict bit fields to having integer types, and to having no more bits than the type specified.
C89 restricts bit fields to (signed) int and unsigned int only, although later standards note that additional types may be supported. ORCA/C supports the other integer types as an extension.

This fixes the compco01.c test case.
2017-10-21 20:36:20 -05:00
Stephen Heumann
05a0ce738a Permit unions to be initialized by assignment from expressions of the appropriate union type.
This patch should also permit the union initialization code to handle unions containing bit fields, but for the time being they are still prohibited by code elsewhere in the compiler.
2017-10-21 20:36:20 -05:00
Stephen Heumann
0705a337b0 Allow case labels in switch statements that are out of range of the type being switched on.
The case label values are converted to the promoted type of the expression being switched on, as if by a cast. In practice, this means discarding the high bits of a 32-bit value to produce a 16-bit one.

Code requiring this is dubious and would be a good candidate for a warning or a lint error, but it's allowed under the C standards.

The following code demonstrates the issue:

#include <stdio.h>
int main(void)
{
    int i = 0x1234;
    switch (i) {
        case 0xABCD1234:
            puts("good");
            break;
        default:
            puts("bad");
    }
}
2017-10-21 20:36:20 -05:00
Stephen Heumann
c77bca8389 When arrays are declared using a typedef'd incomplete array type, don't fix the size for all arrays of that type based on the initializer of the first array using it.
This fixes the compca07.c test case.
2017-10-21 20:36:20 -05:00
Stephen Heumann
d65cc99d9a Fix bug where globals or static variables initialized with the address-of operator and pointer arithmetic could get the wrong value.
For example, p would not be correctly initialized given the following global definitions:
int a = 4;
int *p = &a + 1; /* *(p-1) should be 4 */
2017-10-21 20:36:20 -05:00
Stephen Heumann
8e7f46dc99 Fix bug where globals or static variables initialized using pointer arithmetic on string constants could get the wrong value.
This fixes the compca16.c test case.
2017-10-21 20:36:20 -05:00
Stephen Heumann
46b6aa389f Change all text/source files to LF line endings. 2017-10-21 18:40:19 -05:00
mikew50
e72177985e ORCA/C 2.1.0 source from the Opus ][ CD 2017-10-01 17:47:47 -06:00