Skip to content

Commit

Permalink
Add test for bootstrap compiler TypeQualifiers (#746)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer authored Jan 29, 2025
1 parent aaea818 commit fdd1f14
Show file tree
Hide file tree
Showing 31 changed files with 196 additions and 165 deletions.
2 changes: 1 addition & 1 deletion .run/spice build.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice build" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O2 -d ../../src-bootstrap/main.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice build" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O0 -g -d -ir ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_ADDITIONAL_FLAGS" value="-lole32 -lws2_32" />
<env name="LLVM_BUILD_INCLUDE_DIR" value="$PROJECT_DIR$/../llvm-project-latest/build/include" />
Expand Down
6 changes: 4 additions & 2 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import "bootstrap/symboltablebuilder/type-chain";
import "bootstrap/symboltablebuilder/type-qualifiers";

// Wrapper for 'spice test' unit test
f<int> main() {

testTypeQualifiersSmoke();
printf("All assertions passed!");
}
46 changes: 31 additions & 15 deletions src-bootstrap/symboltablebuilder/type-qualifiers.spice
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,12 @@ public type TypeQualifiers struct {
public bool isComposition = false
}

public p TypeQualifiers.ctor() {}

public p TypeQualifiers.ctor(bool isConst, bool isSigned, bool isUnsigned, bool isHeap) {
this.isConst = isConst;
this.isSigned = isSigned;
this.isUnsigned = isUnsigned;
this.isHeap = isHeap;
}

public f<TypeQualifiers> getTypeQualifiersOf(unsigned short superType) {
public f<TypeQualifiers> getTypeQualifiersOf(SuperType superType) {
switch superType {
case SuperType::TY_DOUBLE, SuperType::TY_INT, SuperType::TY_SHORT, SuperType::TY_LONG: {
return TypeQualifiers{
/*isConst=*/false,
/*isSigned*/false,
/*isSigned*/true,
/*isUnsigned*/false,
/*isHeap*/false,
/*isPublic*/false,
Expand Down Expand Up @@ -147,16 +138,16 @@ public p TypeQualifiers.eraseWithMask(const TypeQualifiers& mask) {
this.setBit(i, false);

// If we set the signed/unsigned bit to zero, we need to set the other to one
if i == BIT_INDEX_SIGNED {
if i == BIT_INDEX_SIGNED {
this.setBit(BIT_INDEX_UNSIGNED, true);
} else if i == BIT_INDEX_UNSIGNED {
} else if i == BIT_INDEX_UNSIGNED {
this.setBit(BIT_INDEX_SIGNED, true);
}
}
}
}
}

public p operator==(const TypeQualifiers& lhs, const TypeQualifiers& rhs) {
public f<bool> operator==(const TypeQualifiers& lhs, const TypeQualifiers& rhs) {
const bool isConst = lhs.isConst == rhs.isConst;
const bool isSigned = lhs.isSigned == rhs.isSigned;
const bool isUnsigned = lhs.isUnsigned == rhs.isUnsigned;
Expand Down Expand Up @@ -189,3 +180,28 @@ p TypeQualifiers.setBit(unsigned short index, bool value) {
default: { panic(Error("Bit index fallthrough")); }
}
}

#[test, test.name="TypeQualifiers Smoke test"]
public f<bool> testTypeQualifiersSmoke() {
TypeQualifiers tqInt = getTypeQualifiersOf(SuperType::TY_INT);
assert !tqInt.isConst && tqInt.isSigned && !tqInt.isUnsigned && !tqInt.isHeap && !tqInt.isPublic && !tqInt.isInline && !tqInt.isComposition;

TypeQualifiers tqGeneric = getTypeQualifiersOf(SuperType::TY_GENERIC);
assert !tqGeneric.isConst && !tqGeneric.isSigned && !tqGeneric.isUnsigned && !tqGeneric.isHeap && !tqGeneric.isPublic && !tqGeneric.isInline && !tqGeneric.isComposition;

// test merge
TypeQualifiers merged = tqGeneric.merge(tqInt);
assert !merged.isConst && merged.isSigned && !merged.isUnsigned && !merged.isHeap && !merged.isPublic && !merged.isInline && !merged.isComposition;

// test match
TypeQualifiers tqShort = getTypeQualifiersOf(SuperType::TY_SHORT);
assert !tqShort.isConst && tqShort.isSigned && !tqShort.isUnsigned && !tqShort.isHeap && !tqShort.isPublic && !tqShort.isInline && !tqShort.isComposition;
assert tqShort.match(tqShort, false);

// test eraseWithMask
TypeQualifiers tqGenericCopy = tqGeneric;
tqGenericCopy.eraseWithMask(tqShort);
assert !tqGenericCopy.isConst && !tqGenericCopy.isSigned && tqGenericCopy.isUnsigned && !tqGenericCopy.isHeap && !tqGenericCopy.isPublic && !tqGenericCopy.isInline && !tqGenericCopy.isComposition;

return true;
}
2 changes: 1 addition & 1 deletion src/irgenerator/GenStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ std::any IRGenerator::visitAssertStmt(const AssertStmtNode *node) {
// Switch to then block
switchToBlock(bThen);
// Create constant for error message
const std::string errorMsg = "Assertion failed: Condition '" + node->expressionString + "' evaluated to false.";
const std::string errorMsg = "Assertion failed: Condition '" + node->expressionString + "' evaluated to false.\n";
llvm::Constant *globalString = builder.CreateGlobalStringPtr(errorMsg, getUnusedGlobalName(ANON_GLOBAL_STRING_NAME));
// Print the error message
llvm::Function *printfFct = stdFunctionManager.getPrintfFct();
Expand Down
12 changes: 6 additions & 6 deletions src/symboltablebuilder/TypeQualifiers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TypeQualifiers TypeQualifiers::of(uint16_t superType) {
case TY_INT: // fall-through
case TY_SHORT: // fall-through
case TY_LONG:
return {/*const*/ false, /*signed*/ true, /*unsigned*/ false, /*heap*/ false};
return {/*const*/ false, /*signed*/ true, /*unsigned*/ false};
case TY_BYTE: // fall-through
case TY_CHAR: // fall-through
case TY_STRING: // fall-through
Expand All @@ -31,19 +31,19 @@ TypeQualifiers TypeQualifiers::of(uint16_t superType) {
case TY_INTERFACE: // fall-through
case TY_FUNCTION: // fall-through
case TY_PROCEDURE:
return {/*const*/ false, /*signed*/ false, /*unsigned*/ true, /*heap*/ false};
return {/*const*/ false, /*signed*/ false, /*unsigned*/ true};
case TY_GENERIC:
// Generics must be non-signed and non-unsigned at the same time to ensure a proper function matching
return {/*const*/ false, /*signed*/ false, /*unsigned*/ false, /*heap*/ false};
return {/*const*/ false, /*signed*/ false, /*unsigned*/ false};
case TY_ENUM: // fall-through
case TY_ALIAS: // fall-through
case TY_IMPORT:
return {/*const*/ true, /*signed*/ false, /*unsigned*/ true, /*heap*/ false};
return {/*const*/ true, /*signed*/ false, /*unsigned*/ true};
case TY_DYN: // fall-through
case TY_INVALID: // fall-through
case TY_UNRESOLVED:
// Return all-false qalifiers to not match anything
return {/*const*/ false, /*signed*/ false, /*unsigned*/ false, /*heap*/ false};
// Return all-false qualifiers to not match anything
return {/*const*/ false, /*signed*/ false, /*unsigned*/ false};
default:
throw CompilerError(UNHANDLED_BRANCH, "Symbol qualifier fallthrough"); // GCOV_EXCL_LINE
}
Expand Down
3 changes: 1 addition & 2 deletions src/symboltablebuilder/TypeQualifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ class TypeQualifiers {
public:
// Constructors
TypeQualifiers() = default;
TypeQualifiers(bool isConst, bool isSigned, bool isUnsigned, bool isHeap)
: isConst(isConst), isSigned(isSigned), isUnsigned(isUnsigned), isHeap(isHeap) {}
TypeQualifiers(bool isConst, bool isSigned, bool isUnsigned) : isConst(isConst), isSigned(isSigned), isUnsigned(isUnsigned) {}

// Public static methods
static TypeQualifiers of(uint16_t superType);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
All assertions passed!
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import "bootstrap/symboltablebuilder/type-qualifiers";

// Wrapper for 'spice test' unit test
f<int> main() {
testTypeQualifiersSmoke();
printf("All assertions passed!");
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
First assertion was true
Assertion failed: Condition '1 != 1' evaluated to false.
Assertion failed: Condition '1 != 1' evaluated to false.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"

@anon.string.0 = private unnamed_addr constant [55 x i8] c"Assertion failed: Condition 'true' evaluated to false.\00", align 1
@anon.string.0 = private unnamed_addr constant [56 x i8] c"Assertion failed: Condition 'true' evaluated to false.\0A\00", align 1
@printf.str.0 = private unnamed_addr constant [26 x i8] c"First assertion was true\0A\00", align 1
@anon.string.1 = private unnamed_addr constant [57 x i8] c"Assertion failed: Condition '1 != 1' evaluated to false.\00", align 1
@anon.string.1 = private unnamed_addr constant [58 x i8] c"Assertion failed: Condition '1 != 1' evaluated to false.\0A\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,31 @@ source_filename = "source.spice"
%interface.IIterator = type { ptr }
%struct.Pair = type { i64, ptr }

@anon.string.0 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.getSize() == 3' evaluated to false.\00", align 1
@anon.string.1 = private unnamed_addr constant [63 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\00", align 1
@anon.string.2 = private unnamed_addr constant [66 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\00", align 1
@anon.string.3 = private unnamed_addr constant [66 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\00", align 1
@anon.string.4 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == 4321' evaluated to false.\00", align 1
@anon.string.5 = private unnamed_addr constant [63 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\00", align 1
@anon.string.6 = private unnamed_addr constant [71 x i8] c"Assertion failed: Condition 'pair.getFirst() == 2' evaluated to false.\00", align 1
@anon.string.7 = private unnamed_addr constant [75 x i8] c"Assertion failed: Condition 'pair.getSecond() == 9876' evaluated to false.\00", align 1
@anon.string.8 = private unnamed_addr constant [64 x i8] c"Assertion failed: Condition '!it.isValid()' evaluated to false.\00", align 1
@anon.string.9 = private unnamed_addr constant [63 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\00", align 1
@anon.string.10 = private unnamed_addr constant [66 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\00", align 1
@anon.string.11 = private unnamed_addr constant [63 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\00", align 1
@anon.string.12 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == 4321' evaluated to false.\00", align 1
@anon.string.13 = private unnamed_addr constant [66 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\00", align 1
@anon.string.14 = private unnamed_addr constant [66 x i8] c"Assertion failed: Condition 'it.get() == -99' evaluated to false.\00", align 1
@anon.string.15 = private unnamed_addr constant [64 x i8] c"Assertion failed: Condition '!it.isValid()' evaluated to false.\00", align 1
@anon.string.16 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'vi.get(0) == 123' evaluated to false.\00", align 1
@anon.string.17 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(1) == 4321' evaluated to false.\00", align 1
@anon.string.18 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(2) == 9876' evaluated to false.\00", align 1
@anon.string.19 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'vi.get(0) == 124' evaluated to false.\00", align 1
@anon.string.20 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(1) == 4322' evaluated to false.\00", align 1
@anon.string.21 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(2) == 9877' evaluated to false.\00", align 1
@anon.string.22 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'vi.get(0) == 124' evaluated to false.\00", align 1
@anon.string.23 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(1) == 4323' evaluated to false.\00", align 1
@anon.string.24 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(2) == 9879' evaluated to false.\00", align 1
@anon.string.0 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.getSize() == 3' evaluated to false.\0A\00", align 1
@anon.string.1 = private unnamed_addr constant [64 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\0A\00", align 1
@anon.string.2 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\0A\00", align 1
@anon.string.3 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\0A\00", align 1
@anon.string.4 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'it.get() == 4321' evaluated to false.\0A\00", align 1
@anon.string.5 = private unnamed_addr constant [64 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\0A\00", align 1
@anon.string.6 = private unnamed_addr constant [72 x i8] c"Assertion failed: Condition 'pair.getFirst() == 2' evaluated to false.\0A\00", align 1
@anon.string.7 = private unnamed_addr constant [76 x i8] c"Assertion failed: Condition 'pair.getSecond() == 9876' evaluated to false.\0A\00", align 1
@anon.string.8 = private unnamed_addr constant [65 x i8] c"Assertion failed: Condition '!it.isValid()' evaluated to false.\0A\00", align 1
@anon.string.9 = private unnamed_addr constant [64 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\0A\00", align 1
@anon.string.10 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\0A\00", align 1
@anon.string.11 = private unnamed_addr constant [64 x i8] c"Assertion failed: Condition 'it.isValid()' evaluated to false.\0A\00", align 1
@anon.string.12 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'it.get() == 4321' evaluated to false.\0A\00", align 1
@anon.string.13 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == 123' evaluated to false.\0A\00", align 1
@anon.string.14 = private unnamed_addr constant [67 x i8] c"Assertion failed: Condition 'it.get() == -99' evaluated to false.\0A\00", align 1
@anon.string.15 = private unnamed_addr constant [65 x i8] c"Assertion failed: Condition '!it.isValid()' evaluated to false.\0A\00", align 1
@anon.string.16 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(0) == 123' evaluated to false.\0A\00", align 1
@anon.string.17 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.get(1) == 4321' evaluated to false.\0A\00", align 1
@anon.string.18 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.get(2) == 9876' evaluated to false.\0A\00", align 1
@anon.string.19 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(0) == 124' evaluated to false.\0A\00", align 1
@anon.string.20 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.get(1) == 4322' evaluated to false.\0A\00", align 1
@anon.string.21 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.get(2) == 9877' evaluated to false.\0A\00", align 1
@anon.string.22 = private unnamed_addr constant [68 x i8] c"Assertion failed: Condition 'vi.get(0) == 124' evaluated to false.\0A\00", align 1
@anon.string.23 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.get(1) == 4323' evaluated to false.\0A\00", align 1
@anon.string.24 = private unnamed_addr constant [69 x i8] c"Assertion failed: Condition 'vi.get(2) == 9879' evaluated to false.\0A\00", align 1
@printf.str.0 = private unnamed_addr constant [24 x i8] c"All assertions passed!\0A\00", align 1, !dbg !0

; Function Attrs: noinline nounwind optnone uwtable
Expand Down Expand Up @@ -488,7 +488,7 @@ attributes #2 = { cold noreturn nounwind }
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "printf.str.0", linkageName: "printf.str.0", scope: !2, file: !5, line: 68, type: !6, isLocal: true, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "spice version dev (https://github.com/spicelang/spice)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
!3 = !DIFile(filename: "/home/marc/Documents/Dev/spice/cmake-build-debug/test/./test-files/irgenerator/debug-info/success-dbg-info-complex/source.spice", directory: "./test-files/irgenerator/debug-info/success-dbg-info-complex")
!3 = !DIFile(filename: "/home/marc/Documents/Dev/spice/cmake-build-release/test/./test-files/irgenerator/debug-info/success-dbg-info-complex/source.spice", directory: "./test-files/irgenerator/debug-info/success-dbg-info-complex")
!4 = !{!0}
!5 = !DIFile(filename: "source.spice", directory: "./test-files/irgenerator/debug-info/success-dbg-info-complex")
!6 = !DIStringType(name: "printf.str.0", size: 192)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ attributes #2 = { nofree nounwind }
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "anon.string.0", linkageName: "anon.string.0", scope: !2, file: !7, line: 8, type: !15, isLocal: true, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "spice version dev (https://github.com/spicelang/spice)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
!3 = !DIFile(filename: "/home/marc/Documents/Dev/spice/cmake-build-debug/test/./test-files/irgenerator/debug-info/success-dbg-info-simple/source.spice", directory: "./test-files/irgenerator/debug-info/success-dbg-info-simple")
!3 = !DIFile(filename: "/home/marc/Documents/Dev/spice/cmake-build-release/test/./test-files/irgenerator/debug-info/success-dbg-info-simple/source.spice", directory: "./test-files/irgenerator/debug-info/success-dbg-info-simple")
!4 = !{!0, !5, !9, !12}
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
!6 = distinct !DIGlobalVariable(name: "printf.str.0", linkageName: "printf.str.0", scope: !2, file: !7, line: 15, type: !8, isLocal: true, isDefinition: true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ source_filename = "source.spice"
@anon.string.0 = private unnamed_addr constant [6 x i8] c"Hello\00", align 1
@anon.string.1 = private unnamed_addr constant [6 x i8] c"World\00", align 1
@anon.array.0 = private unnamed_addr constant [2 x ptr] [ptr @anon.string.0, ptr @anon.string.1]
@anon.string.2 = private unnamed_addr constant [62 x i8] c"Assertion failed: Condition '*iPtr == 13' evaluated to false.\00", align 1
@anon.string.2 = private unnamed_addr constant [63 x i8] c"Assertion failed: Condition '*iPtr == 13' evaluated to false.\0A\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"

@anon.string.0 = private unnamed_addr constant [57 x i8] c"Assertion failed: Condition 'x == 6' evaluated to false.\00", align 1
@anon.string.1 = private unnamed_addr constant [58 x i8] c"Assertion failed: Condition 'foo2(x)' evaluated to false.\00", align 1
@anon.string.2 = private unnamed_addr constant [58 x i8] c"Assertion failed: Condition 'x == 11' evaluated to false.\00", align 1
@anon.string.0 = private unnamed_addr constant [58 x i8] c"Assertion failed: Condition 'x == 6' evaluated to false.\0A\00", align 1
@anon.string.1 = private unnamed_addr constant [59 x i8] c"Assertion failed: Condition 'foo2(x)' evaluated to false.\0A\00", align 1
@anon.string.2 = private unnamed_addr constant [59 x i8] c"Assertion failed: Condition 'x == 11' evaluated to false.\0A\00", align 1
@printf.str.0 = private unnamed_addr constant [19 x i8] c"All tests passed!\0A\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
Expand Down
Loading

0 comments on commit fdd1f14

Please sign in to comment.