1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-29 03:56:15 +00:00

Added tests for #pragma constructor_for() errors. Closes #511

This commit is contained in:
jespergravgaard 2020-08-25 00:27:42 +02:00
parent 5d81c1260f
commit 7d82543566
9 changed files with 750 additions and 0 deletions

View File

@ -42,11 +42,31 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testLibraryConstructorError2() throws IOException, URISyntaxException {
assertError("library-constructor-error-2.c", "Error! Procedure not found print");
}
@Test
public void testLibraryConstructorError1() throws IOException, URISyntaxException {
assertError("library-constructor-error-1.c", "Error! Constructor procedure not found my_init");
}
@Test
public void testLibraryConstructorError0() throws IOException, URISyntaxException {
assertError("library-constructor-error-0.c", "Error! #pragma constructor_for requires at least 2 parameters.");
}
@Test
public void testLibraryConstructor2() throws IOException, URISyntaxException {
compileAndCompare("library-constructor-2.c");
}
@Test
public void testLibraryConstructor3() throws IOException, URISyntaxException {
compileAndCompare("library-constructor-3.c", log());
}
@Test
public void testLibraryConstructor1() throws IOException, URISyntaxException {
compileAndCompare("library-constructor-1.c");

View File

@ -0,0 +1,25 @@
// Demonstrates Library Constructor Functionality
// Multiple #pragma constructor_for() constructors
#pragma constructor_for(init_1, print)
#pragma constructor_for(init_2, print)
volatile char sym;
char * volatile SCREEN;
void init_1(void) {
sym = '*';
}
void init_2(void) {
SCREEN = 0x0400;
}
void main(void) {
print();
}
void print() {
*SCREEN = sym;
}

View File

@ -0,0 +1,14 @@
// Demonstrates Library Constructor Functionality
// To few parameters for pragma
#pragma constructor_for(my_init)
// Constructor
void my_init(void) {
}
char * const SCREEN = 0x0400;
void main(void) {
}

View File

@ -0,0 +1,10 @@
// Demonstrates Library Constructor Functionality
// Init procedure not found
#pragma constructor_for(my_init, main)
char * const SCREEN = 0x0400;
void main(void) {
}

View File

@ -0,0 +1,14 @@
// Demonstrates Library Constructor Functionality
// Init procedure not found
#pragma constructor_for(my_init, print)
char * const SCREEN = 0x0400;
// Constructor
void my_init(void) {
}
void main(void) {
}

View File

@ -0,0 +1,53 @@
// Demonstrates Library Constructor Functionality
// Multiple #pragma constructor_for() constructors
.pc = $801 "Basic"
:BasicUpstart(__start)
.pc = $80d "Program"
.label sym = 2
.label SCREEN = 3
__start: {
// sym
lda #0
sta.z sym
// SCREEN
sta.z SCREEN
sta.z SCREEN+1
// #pragma constructor_for(init_1, print)
//#pragma constructor
jsr init_1
// #pragma constructor_for(init_2, print)
//#pragma constructor
jsr init_2
jsr main
rts
}
init_2: {
// SCREEN = 0x0400
lda #<$400
sta.z SCREEN
lda #>$400
sta.z SCREEN+1
// }
rts
}
init_1: {
// sym = '*'
lda #'*'
sta.z sym
// }
rts
}
main: {
// print()
jsr print
// }
rts
}
print: {
// *SCREEN = sym
lda.z sym
ldy #0
sta (SCREEN),y
// }
rts
}

View File

@ -0,0 +1,54 @@
(void()) __start()
__start: scope:[__start] from
[0] phi()
to:__start::__init1
__start::__init1: scope:[__start] from __start
[1] (volatile byte) sym ← (byte) 0
[2] (volatile byte*) SCREEN ← (byte*) 0
[3] call init_1
to:__start::@2
__start::@2: scope:[__start] from __start::__init1
[4] phi()
[5] call init_2
to:__start::@1
__start::@1: scope:[__start] from __start::@2
[6] phi()
[7] call main
to:__start::@return
__start::@return: scope:[__start] from __start::@1
[8] return
to:@return
(void()) init_2()
init_2: scope:[init_2] from __start::@2
[9] (volatile byte*) SCREEN ← (byte*) 1024
to:init_2::@return
init_2::@return: scope:[init_2] from init_2
[10] return
to:@return
(void()) init_1()
init_1: scope:[init_1] from __start::__init1
[11] (volatile byte) sym ← (byte) '*'
to:init_1::@return
init_1::@return: scope:[init_1] from init_1
[12] return
to:@return
(void()) main()
main: scope:[main] from __start::@1
[13] phi()
[14] call print
to:main::@return
main::@return: scope:[main] from main
[15] return
to:@return
(void()) print()
print: scope:[print] from main
[16] *((volatile byte*) SCREEN) ← (volatile byte) sym
to:print::@return
print::@return: scope:[print] from print
[17] return
to:@return

View File

@ -0,0 +1,542 @@
Inlined call call __init
CONTROL FLOW GRAPH SSA
(void()) init_1()
init_1: scope:[init_1] from __start::__init1
(volatile byte) sym ← (byte) '*'
to:init_1::@return
init_1::@return: scope:[init_1] from init_1
return
to:@return
(void()) init_2()
init_2: scope:[init_2] from __start::@2
(volatile byte*) SCREEN ← ((byte*)) (number) $400
to:init_2::@return
init_2::@return: scope:[init_2] from init_2
return
to:@return
(void()) main()
main: scope:[main] from __start::@1
call print
to:main::@1
main::@1: scope:[main] from main
to:main::@return
main::@return: scope:[main] from main::@1
return
to:@return
(void()) print()
print: scope:[print] from main
*((volatile byte*) SCREEN) ← (volatile byte) sym
to:print::@return
print::@return: scope:[print] from print
return
to:@return
(void()) __start()
__start: scope:[__start] from
to:__start::__init1
__start::__init1: scope:[__start] from __start
(volatile byte) sym ← (byte) 0
(volatile byte*) SCREEN ← (byte*) 0
call init_1
to:__start::@2
__start::@2: scope:[__start] from __start::__init1
call init_2
to:__start::@3
__start::@3: scope:[__start] from __start::@2
to:__start::@1
__start::@1: scope:[__start] from __start::@3
call main
to:__start::@4
__start::@4: scope:[__start] from __start::@1
to:__start::@return
__start::@return: scope:[__start] from __start::@4
return
to:@return
SYMBOL TABLE SSA
(volatile byte*) SCREEN loadstore
(void()) __start()
(label) __start::@1
(label) __start::@2
(label) __start::@3
(label) __start::@4
(label) __start::@return
(label) __start::__init1
(void()) init_1()
(label) init_1::@return
(void()) init_2()
(label) init_2::@return
(void()) main()
(label) main::@1
(label) main::@return
(void()) print()
(label) print::@return
(volatile byte) sym loadstore
Inlining cast (volatile byte*) SCREEN ← (byte*)(number) $400
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Adding NOP phi() at start of __start
Adding NOP phi() at start of __start::@2
Adding NOP phi() at start of __start::@3
Adding NOP phi() at start of __start::@1
Adding NOP phi() at start of __start::@4
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
CALL GRAPH
Calls in [__start] to init_1:3 init_2:5 main:8
Calls in [main] to print:16
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) __start::@3
Culled Empty Block (label) __start::@4
Culled Empty Block (label) main::@1
Adding NOP phi() at start of __start
Adding NOP phi() at start of __start::@2
Adding NOP phi() at start of __start::@1
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
(void()) __start()
__start: scope:[__start] from
[0] phi()
to:__start::__init1
__start::__init1: scope:[__start] from __start
[1] (volatile byte) sym ← (byte) 0
[2] (volatile byte*) SCREEN ← (byte*) 0
[3] call init_1
to:__start::@2
__start::@2: scope:[__start] from __start::__init1
[4] phi()
[5] call init_2
to:__start::@1
__start::@1: scope:[__start] from __start::@2
[6] phi()
[7] call main
to:__start::@return
__start::@return: scope:[__start] from __start::@1
[8] return
to:@return
(void()) init_2()
init_2: scope:[init_2] from __start::@2
[9] (volatile byte*) SCREEN ← (byte*) 1024
to:init_2::@return
init_2::@return: scope:[init_2] from init_2
[10] return
to:@return
(void()) init_1()
init_1: scope:[init_1] from __start::__init1
[11] (volatile byte) sym ← (byte) '*'
to:init_1::@return
init_1::@return: scope:[init_1] from init_1
[12] return
to:@return
(void()) main()
main: scope:[main] from __start::@1
[13] phi()
[14] call print
to:main::@return
main::@return: scope:[main] from main
[15] return
to:@return
(void()) print()
print: scope:[print] from main
[16] *((volatile byte*) SCREEN) ← (volatile byte) sym
to:print::@return
print::@return: scope:[print] from print
[17] return
to:@return
VARIABLE REGISTER WEIGHTS
(volatile byte*) SCREEN loadstore 22.8
(void()) __start()
(void()) init_1()
(void()) init_2()
(void()) main()
(void()) print()
(volatile byte) sym loadstore 16.285714285714285
Initial phi equivalence classes
Added variable sym to live range equivalence class [ sym ]
Added variable SCREEN to live range equivalence class [ SCREEN ]
Complete equivalence classes
[ sym ]
[ SCREEN ]
Allocated zp[1]:2 [ sym ]
Allocated zp[2]:3 [ SCREEN ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Demonstrates Library Constructor Functionality
// Multiple #pragma constructor_for() constructors
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__start)
.pc = $80d "Program"
// Global Constants & labels
.label sym = 2
.label SCREEN = 3
// __start
__start: {
jmp __init1
// __start::__init1
__init1:
// [1] (volatile byte) sym ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z sym
// [2] (volatile byte*) SCREEN ← (byte*) 0 -- pbuz1=pbuc1
lda #<0
sta.z SCREEN
lda #>0
sta.z SCREEN+1
// [3] call init_1
//#pragma constructor
jsr init_1
// [4] phi from __start::__init1 to __start::@2 [phi:__start::__init1->__start::@2]
__b2_from___init1:
jmp __b2
// __start::@2
__b2:
// [5] call init_2
//#pragma constructor
jsr init_2
// [6] phi from __start::@2 to __start::@1 [phi:__start::@2->__start::@1]
__b1_from___b2:
jmp __b1
// __start::@1
__b1:
// [7] call main
// [13] phi from __start::@1 to main [phi:__start::@1->main]
main_from___b1:
jsr main
jmp __breturn
// __start::@return
__breturn:
// [8] return
rts
}
// init_2
init_2: {
// [9] (volatile byte*) SCREEN ← (byte*) 1024 -- pbuz1=pbuc1
lda #<$400
sta.z SCREEN
lda #>$400
sta.z SCREEN+1
jmp __breturn
// init_2::@return
__breturn:
// [10] return
rts
}
// init_1
init_1: {
// [11] (volatile byte) sym ← (byte) '*' -- vbuz1=vbuc1
lda #'*'
sta.z sym
jmp __breturn
// init_1::@return
__breturn:
// [12] return
rts
}
// main
main: {
// [14] call print
jsr print
jmp __breturn
// main::@return
__breturn:
// [15] return
rts
}
// print
print: {
// [16] *((volatile byte*) SCREEN) ← (volatile byte) sym -- _deref_pbuz1=vbuz2
lda.z sym
ldy #0
sta (SCREEN),y
jmp __breturn
// print::@return
__breturn:
// [17] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] (volatile byte) sym ← (byte) 0 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] (volatile byte*) SCREEN ← (byte*) 0 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [9] (volatile byte*) SCREEN ← (byte*) 1024 [ SCREEN ] ( [ SCREEN ] { } init_2:5 [ sym SCREEN ] { } ) always clobbers reg byte a
Statement [11] (volatile byte) sym ← (byte) '*' [ sym ] ( [ sym ] { } init_1:3 [ sym ] { } ) always clobbers reg byte a
Statement [16] *((volatile byte*) SCREEN) ← (volatile byte) sym [ ] ( main:7::print:14 [ ] { } ) always clobbers reg byte a reg byte y
Potential registers zp[1]:2 [ sym ] : zp[1]:2 ,
Potential registers zp[2]:3 [ SCREEN ] : zp[2]:3 ,
REGISTER UPLIFT SCOPES
Uplift Scope [] 22.8: zp[2]:3 [ SCREEN ] 16.29: zp[1]:2 [ sym ]
Uplift Scope [init_1]
Uplift Scope [init_2]
Uplift Scope [main]
Uplift Scope [print]
Uplift Scope [__start]
Uplifting [] best 146 combination zp[2]:3 [ SCREEN ] zp[1]:2 [ sym ]
Uplifting [init_1] best 146 combination
Uplifting [init_2] best 146 combination
Uplifting [main] best 146 combination
Uplifting [print] best 146 combination
Uplifting [__start] best 146 combination
Attempting to uplift remaining variables inzp[1]:2 [ sym ]
Uplifting [] best 146 combination zp[1]:2 [ sym ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Demonstrates Library Constructor Functionality
// Multiple #pragma constructor_for() constructors
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__start)
.pc = $80d "Program"
// Global Constants & labels
.label sym = 2
.label SCREEN = 3
// __start
__start: {
jmp __init1
// __start::__init1
__init1:
// [1] (volatile byte) sym ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z sym
// [2] (volatile byte*) SCREEN ← (byte*) 0 -- pbuz1=pbuc1
lda #<0
sta.z SCREEN
lda #>0
sta.z SCREEN+1
// [3] call init_1
//#pragma constructor
jsr init_1
// [4] phi from __start::__init1 to __start::@2 [phi:__start::__init1->__start::@2]
__b2_from___init1:
jmp __b2
// __start::@2
__b2:
// [5] call init_2
//#pragma constructor
jsr init_2
// [6] phi from __start::@2 to __start::@1 [phi:__start::@2->__start::@1]
__b1_from___b2:
jmp __b1
// __start::@1
__b1:
// [7] call main
// [13] phi from __start::@1 to main [phi:__start::@1->main]
main_from___b1:
jsr main
jmp __breturn
// __start::@return
__breturn:
// [8] return
rts
}
// init_2
init_2: {
// [9] (volatile byte*) SCREEN ← (byte*) 1024 -- pbuz1=pbuc1
lda #<$400
sta.z SCREEN
lda #>$400
sta.z SCREEN+1
jmp __breturn
// init_2::@return
__breturn:
// [10] return
rts
}
// init_1
init_1: {
// [11] (volatile byte) sym ← (byte) '*' -- vbuz1=vbuc1
lda #'*'
sta.z sym
jmp __breturn
// init_1::@return
__breturn:
// [12] return
rts
}
// main
main: {
// [14] call print
jsr print
jmp __breturn
// main::@return
__breturn:
// [15] return
rts
}
// print
print: {
// [16] *((volatile byte*) SCREEN) ← (volatile byte) sym -- _deref_pbuz1=vbuz2
lda.z sym
ldy #0
sta (SCREEN),y
jmp __breturn
// print::@return
__breturn:
// [17] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __init1
Removing instruction jmp __b2
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #<0
Removing instruction lda #>0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b2_from___init1:
Removing instruction __b1_from___b2:
Removing instruction main_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __init1:
Removing instruction __b2:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(volatile byte*) SCREEN loadstore zp[2]:3 22.8
(void()) __start()
(label) __start::@1
(label) __start::@2
(label) __start::@return
(label) __start::__init1
(void()) init_1()
(label) init_1::@return
(void()) init_2()
(label) init_2::@return
(void()) main()
(label) main::@return
(void()) print()
(label) print::@return
(volatile byte) sym loadstore zp[1]:2 16.285714285714285
zp[1]:2 [ sym ]
zp[2]:3 [ SCREEN ]
FINAL ASSEMBLER
Score: 91
// File Comments
// Demonstrates Library Constructor Functionality
// Multiple #pragma constructor_for() constructors
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__start)
.pc = $80d "Program"
// Global Constants & labels
.label sym = 2
.label SCREEN = 3
// __start
__start: {
// __start::__init1
// sym
// [1] (volatile byte) sym ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z sym
// SCREEN
// [2] (volatile byte*) SCREEN ← (byte*) 0 -- pbuz1=pbuc1
sta.z SCREEN
sta.z SCREEN+1
// #pragma constructor_for(init_1, print)
// [3] call init_1
//#pragma constructor
jsr init_1
// [4] phi from __start::__init1 to __start::@2 [phi:__start::__init1->__start::@2]
// __start::@2
// #pragma constructor_for(init_2, print)
// [5] call init_2
//#pragma constructor
jsr init_2
// [6] phi from __start::@2 to __start::@1 [phi:__start::@2->__start::@1]
// __start::@1
// [7] call main
// [13] phi from __start::@1 to main [phi:__start::@1->main]
jsr main
// __start::@return
// [8] return
rts
}
// init_2
init_2: {
// SCREEN = 0x0400
// [9] (volatile byte*) SCREEN ← (byte*) 1024 -- pbuz1=pbuc1
lda #<$400
sta.z SCREEN
lda #>$400
sta.z SCREEN+1
// init_2::@return
// }
// [10] return
rts
}
// init_1
init_1: {
// sym = '*'
// [11] (volatile byte) sym ← (byte) '*' -- vbuz1=vbuc1
lda #'*'
sta.z sym
// init_1::@return
// }
// [12] return
rts
}
// main
main: {
// print()
// [14] call print
jsr print
// main::@return
// }
// [15] return
rts
}
// print
print: {
// *SCREEN = sym
// [16] *((volatile byte*) SCREEN) ← (volatile byte) sym -- _deref_pbuz1=vbuz2
lda.z sym
ldy #0
sta (SCREEN),y
// print::@return
// }
// [17] return
rts
}
// File Data

View File

@ -0,0 +1,18 @@
(volatile byte*) SCREEN loadstore zp[2]:3 22.8
(void()) __start()
(label) __start::@1
(label) __start::@2
(label) __start::@return
(label) __start::__init1
(void()) init_1()
(label) init_1::@return
(void()) init_2()
(label) init_2::@return
(void()) main()
(label) main::@return
(void()) print()
(label) print::@return
(volatile byte) sym loadstore zp[1]:2 16.285714285714285
zp[1]:2 [ sym ]
zp[2]:3 [ SCREEN ]