Coder Social home page Coder Social logo

orca-c's People

Contributors

ksherlock avatar mikew50 avatar sheumann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orca-c's Issues

Preprocessor: # operator does not follow standards

The # operator for stringizing tokens behaves non-standardly in at least the following respects:

  • It does not insert spaces corresponding to white space between its argument tokens.
  • When applied to a string literal, it should generate a string corresponding to the original representation of the string in the source file, including " delimiters and escape sequences using \ (and those characters are at least conceptually escaped with \ to permit this). Currently, it gives a string literal equivalent to the one passed to it, but does not include the delimiters and escape sequences from its actual representation in the source file.

debugger symbol table errors with nested structs

I'm not sure what the correct behavior is... this can be worked around on the debugger side since it consistent (but none of it was properly documented so I'm not sure if it's a bug or not).

given something like:

struct b { int b; };
struct c { int a; struct b b1; struct b b2; };

int test1(void) {
  struct c c;
  return 0;
}

The generated symbol table looks like:

000086 000014 |          COP   $05
00008A 000016 |          DC    I'60'

struct c c
00008D 000018 |          DC    I4'((test1+$0000006A)+$00000010)'
00009B 00001C |          DC    I4'5'
00009F 000020 |          DC    H'00 0C'
0000A1 000022 |          DC    I2'0'

	int a
	0000A4 000024 |          DC    I4'((test1+$0000006A)+$00000012)'
	0000B2 000028 |          DC    I4'0'
	0000B6 00002C |          DC    H'01 01'
	0000B8 00002E |          DC    I2'0'

	struct b b1
	0000BB 000030 |          DC    I4'((test1+$0000006A)+$00000014)'
	0000C9 000034 |          DC    I4'2'
	0000CD 000038 |          DC    H'01 0C'
	0000CF 00003A |          DC    I2'0'

		int b
		0000D2 00003C |          DC    I4'((test1+$0000006A)+$00000017)'
		0000E0 000040 |          DC    I4'0'
		0000E4 000044 |          DC    H'00 01'
		0000E6 000046 |          DC    I2'0'

	reference to struct b b2
	0000E9 000048 |          DC    I4'((test1+$0000006A)+$00000019)'
	0000F7 00004C |          DC    I4'4'
	0000FB 000050 |          DC    H'00 0D'
	0000FD 000052 |          DC    I2'12' <<< should be 24

The second struct, b2, uses a displacement to the first struct. However, the displacement is 12 less than the true displacement (12 less for each nested structure level, in fact).

This may be fixable by adjusting symLength in GenSymbol before calling ExpandStructType:

               symLength := symLength+12; {update length of symbol table}
               ExpandStructType(ip^.itype);
               symLength := symLength-12; {update length of symbol table}

Preprocessor: Cycles of mutually-referential macros cause ORCA/C to infinite-loop

Given code like the following, ORCA/C will get stuck in an infinite loop repeatedly expanding the macros (this also happens with similar code using function-like macros):

#define a b
#define b a
a

In this context, the expansion should go a->b->a and then stop, because it’s nested within a token sequence already expanded from a. (See C90 section 6.8.3.4 or C99/C11 section 6.10.3.4.)

loop invariant bug

/* loop invariant removal causes bad code to be generated */
#pragma lint -1
#pragma optimize -1

int getc(void);
#define EOF -1

unsigned s_flag;

int pager(void) {

    unsigned line = 1;
    unsigned col = 1;
    unsigned prev_col = 0;

    while(1) {
        int c;
        c = getc();
        if (c == EOF)
            break;

        if (c == '\n') {
            if (s_flag && col == 1 && prev_col == 1)
                continue;
            prev_col = col;
            col = 1;
        } else { col++; }

    }
    return 0;
}

generates this code:

; calculating col == 1 and prev_col == 1 outside the loop
000052 000011 |          LDA   $07
000054 000013 |          LDX   #$0000
000057 000016 |          CMP   #$0001
00005A 000019 |          BNE   (pager+$0000001C)
000067 00001B |          INX   
000069 00001C |          TXA   
00006B 00001D |          STA   $09
00006D 00001F |          LDA   $05
00006F 000021 |          LDX   #$0000
000072 000024 |          CMP   #$0001
000075 000027 |          BNE   (pager+$0000002A)
000082 000029 |          INX   
000084 00002A |          TXA   
000086 00002B |          STA   $0B
...
; in the loop...
0000C6 000041 |          LDA   s_flag
0000D3 000044 |          BEQ   (pager+$00000050)
0000E1 000046 |          LDA   $0B
0000E4 000048 |          BEQ   (pager+$00000050)
0000F1 00004A |          LDA   $09
0000F4 00004C |          BEQ   (pager+$00000050)
000101 00004E |          BRA   *-$21

Interestingly enough, replacing while(1) with a for(;;) prevents the loop invariant removal.

ORCA/C 2.2.0 B2

Macro names appearing within the macro are not always blocked from re-expansion

A large number of #define's will cause the compiler to crash and take the OS down with it, presumably during preprocessing. There is a way around this problem, and that is running the code through a stand-alone preprocessor such as "cpp" (using appropriate #define's, of course). The resulting code will likely compile fine under ORCA/C.
[compcr01.shk], dr

When the variable portion of an array index expression is negative, incorrect code will be generated in some cases.

When the variable portion of an array index expression (the part that is not treated as a compile-time constant) is negative, incorrect code (accessing one bank beyond the correct location) will be generated in some cases.

The following program demonstrates the issue:

#pragma optimize 1

char c[100] = {42};

int main(void) {
    int i = -1;
    return c[i+1]; /* should return 42 */
}

This error can occur when calling the is* macros in <ctype.h> with an argument of EOF (-1), since they use the index expression (__ctype)[(c)+1]. (Issue pointed out by Kelvin Sherlock.)

forward-declared struct parameters

forward-declared struct parameters don't cause a compiler error:

int bleh(struct unknown xxx) {
 return 0;
}

[FIXED] Curiously, the parameter is installed in the global symbol table:

int bleh(struct unknown xxx) {
 int xxx; /* not a duplicate symbol */
 return 0;
}

void address_of(void) {
  void *vp = &xxx; /* not an error */
}

int xxx = 0; /* "duplicate symbol" */

[FIXED] On a related note, ORCA/C never checks if forward-declared structs are ever completed

#include <stdio.h>

struct abc abc;
struct def def;

int main(int argc, char **argv) {
  printf("%p %p\n", &abc, &def);
  printf("%d\n", (void *)&abc == (void *)&def);
  return 0;
}

Variable arguments should not be removed from the stack by va_end()

The current way ORCA/C handles variable arguments is non-standard in a few respects. These include that you can’t restart variable argument processing by calling va_start() after va_end(), and that the addresses of local variables will change when va_end() is called (so any pointers to them taken before that are invalid afterward).

These issues stem from the fact that the va_end() macro invokes the __va_end() function, which actually removes the variable arguments from the stack and moves the other stack contents up to fill the space they occupied.

To solve these issues, the variable arguments cannot in general be removed from the stack at the time va_end() is called. If the function taking a variable number of arguments is to remove them at all, it must do so only after all use of the variable arguments, and of any pointers to local variables, is finished. Absent fairly sophisticated analysis, this means it can only be done at the end of the function.

Note that it’s only really necessary to remove the variable arguments if the caller may have #pragma optimize bit 6 set, and that even if done at the end of the function, the length of the variable arguments would have to be determined by how many were accessed, so the non-standard restriction that all of them must be accessed would still apply. This restriction could be removed by changing the calling convention, but that could cause various compatibility problems.

A full solution to these issues would probably require changes to the compiler (to generate code to remove the arguments at the end of the function) and the <stdarg.h> header (to interface with the new compiler mechanism). Depending on the solution adopted, library changes might be needed as well.

#pragma path and system header files

From the GNO FAQ:

Q#611:	Why, when I '#include <types.h>' (or some other file), does the
	compiler take it out of my current directory instead of out of
	the system header directories?

A#611:	This is an unfortunate side-effect of using the ORCA/C "path"
	pragma to avoid duplication of system header files between your
	GNO and ORCA installations.  (See Q#1401, Q#1301, Q#1304, and
	Q#1305.)

	The reason for the problem is that when the file is included
	with the angle bracket syntax (vice double quotes), ORCA/C 
	will still search the current directory before those specified
	by the "path" pragma.

	At this time, the only known work-around is to avoid, in your
	own sources, using file names used by the system header files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.