diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index f738632f3..bca2ba9ab 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -199,6 +199,7 @@ public class Compiler { new Pass1EarlyConstantIdentification(program).execute(); new PassNAssertConstantModification(program).execute(); + new PassNAssertTypeDeref(program).check(); if(getLog().isVerbosePass1CreateSsa()) { getLog().append("CONTROL FLOW GRAPH BEFORE INLINING"); @@ -258,6 +259,7 @@ public class Compiler { private void pass2AssertSSA() { List assertions = new ArrayList<>(); //assertions.add(new Pass2AssertNoLValueObjectEquality(program)); + assertions.add(new PassNAssertTypeDeref(program)); assertions.add(new Pass2AssertTypeMatch(program)); assertions.add(new Pass2AssertSymbols(program)); assertions.add(new Pass2AssertBlocks(program)); diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAssertTypeDeref.java b/src/main/java/dk/camelot64/kickc/passes/PassNAssertTypeDeref.java new file mode 100644 index 000000000..f4c7ccfbd --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAssertTypeDeref.java @@ -0,0 +1,34 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.types.SymbolTypePointer; +import dk.camelot64.kickc.model.values.PointerDereference; +import dk.camelot64.kickc.model.values.RValue; + +/** + * Asserts that all dereferenced values are pointers. + */ +public class PassNAssertTypeDeref extends Pass2SsaAssertion { + + public PassNAssertTypeDeref(Program program) { + super(program); + } + + @Override + public void check() throws AssertionFailed { + ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { + if(programValue.get() instanceof PointerDereference) { + RValue pointer = ((PointerDereference) programValue.get()).getPointer(); + SymbolType pointertype = SymbolTypeInference.inferType(getProgram().getScope(), pointer); + if(!SymbolType.VAR.equals(pointertype) && !(pointertype instanceof SymbolTypePointer)) + throw new CompileError("Error! Dereferencing a non-pointer type "+pointertype.getTypeName(), currentStmt); + } + }); + } + + +} diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index de7b276aa..1dd1fef56 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -432,8 +432,7 @@ public class TestPrograms { @Test public void testFunctionAsArray() throws IOException, URISyntaxException { - compileAndCompare("function-as-array", log().verboseParse().verboseCreateSsa()); - assertError("function-as-array", "Cannot infer pointer element type from type: void()"); + assertError("function-as-array", "Error! Dereferencing a non-pointer type void()"); } @Test @@ -503,7 +502,7 @@ public class TestPrograms { @Test public void testCastError() throws IOException, URISyntaxException { - assertError("cast-error", "cannot be assigned from"); + assertError("cast-error", "Error! Dereferencing a non-pointer type number"); } @Test