mirror of https://github.com/aamine/cbc
* net/loveruby/cflat/compiler/TypeChecker.java: check member validity for s.memb, s->memb, u.memb, u->memb.
* net/loveruby/cflat/type/Type.java: new method #isComplexType. * net/loveruby/cflat/type/ComplexType.java: override it. * net/loveruby/cflat/compiler/LocalReferenceResolver.java: should resolve variable initializer. * net/loveruby/cflat/ast/DefinedVariable.java: new method #hasInitializer. * test/test.sh: run tests. * test/struct-semcheck5.cb: check if member is valid on s.memb. * test/struct-semcheck6.cb: check if member is valid on sptr->memb. * test/union-semcheck5.cb: check if member is valid on u.memb. * test/union-semcheck6.cb: check if member is valid on uptr->memb. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3766 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
0b70938a5f
commit
705818d1dc
26
ChangeLog
26
ChangeLog
|
@ -1,3 +1,29 @@
|
|||
Wed Jan 2 01:24:05 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/TypeChecker.java: check member
|
||||
validity for s.memb, s->memb, u.memb, u->memb.
|
||||
|
||||
* net/loveruby/cflat/type/Type.java: new method #isComplexType.
|
||||
|
||||
* net/loveruby/cflat/type/ComplexType.java: override it.
|
||||
|
||||
* net/loveruby/cflat/compiler/LocalReferenceResolver.java: should
|
||||
resolve variable initializer.
|
||||
|
||||
* net/loveruby/cflat/ast/DefinedVariable.java: new method
|
||||
#hasInitializer.
|
||||
|
||||
* test/test.sh: run tests.
|
||||
|
||||
* test/struct-semcheck5.cb: check if member is valid on s.memb.
|
||||
|
||||
* test/struct-semcheck6.cb: check if member is valid on
|
||||
sptr->memb.
|
||||
|
||||
* test/union-semcheck5.cb: check if member is valid on u.memb.
|
||||
|
||||
* test/union-semcheck6.cb: check if member is valid on uptr->memb.
|
||||
|
||||
Wed Jan 2 00:38:48 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/TypeChecker.java: check aref base
|
||||
|
|
19
ToDo
19
ToDo
|
@ -155,13 +155,23 @@
|
|||
- warn unused static variables
|
||||
- warn unused local variables
|
||||
- warn unused static functions
|
||||
- check if aref base expr is indexable (a must be indeable where a[0])
|
||||
- check if funcall base expr is callable (a must be callable where a())
|
||||
* semantic check (type)
|
||||
- simple type check (binary ops, unary ops)
|
||||
- a[0]
|
||||
- *ptr
|
||||
- ct.memb
|
||||
- ptr->memb
|
||||
- funcall args
|
||||
- prohibit circular struct/union definition
|
||||
* type check
|
||||
* implicit cast
|
||||
* check return type
|
||||
- implicit cast
|
||||
- validate struct/union member (ct.memb)
|
||||
- validate struct/union member (ct->memb)
|
||||
* check duplicated struct/union members
|
||||
* validate struct/union member
|
||||
* ptr + int; ptr - int
|
||||
* check return type
|
||||
* check if assignable
|
||||
- op for various types
|
||||
- signed char
|
||||
- signed short
|
||||
|
@ -186,6 +196,7 @@
|
|||
* warn no return
|
||||
* data flow graph
|
||||
* --dump-dflow
|
||||
* warn unused variable
|
||||
* warn uninitialized use of variables
|
||||
* semantic check (dflow)
|
||||
* register allocation
|
||||
|
|
|
@ -18,10 +18,14 @@ public class DefinedVariable extends Variable {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
public boolean hasInitializer() {
|
||||
return (initializer != null);
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return hasInitializer();
|
||||
}
|
||||
|
||||
public Node initializer() {
|
||||
return initializer;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ public class LocalReferenceResolver extends Visitor {
|
|||
|
||||
public void visit(BlockNode node) {
|
||||
pushScope(node.variables());
|
||||
resolveInitializers(node.variables());
|
||||
super.visit(node);
|
||||
node.setScope(popScope());
|
||||
}
|
||||
|
@ -100,6 +101,15 @@ public class LocalReferenceResolver extends Visitor {
|
|||
return (Scope)scopeStack.getLast();
|
||||
}
|
||||
|
||||
protected void resolveInitializers(Iterator vars) {
|
||||
while (vars.hasNext()) {
|
||||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
if (var.hasInitializer()) {
|
||||
resolve(var.initializer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(StringLiteralNode node) {
|
||||
node.setEntry(constantTable.intern(node.value()));
|
||||
}
|
||||
|
|
|
@ -320,19 +320,39 @@ class TypeChecker extends Visitor {
|
|||
}
|
||||
|
||||
public void visit(MemberNode node) {
|
||||
super.visit(node);
|
||||
// FIXME: validate member here?
|
||||
resolve(node.expr());
|
||||
checkMemberRef(node.expr().type(), node.name());
|
||||
}
|
||||
|
||||
public void visit(PtrMemberNode node) {
|
||||
super.visit(node);
|
||||
// FIXME: validate member here?
|
||||
resolve(node.expr());
|
||||
if (! node.expr().type().isPointer()) {
|
||||
notPointerError(node.type());
|
||||
return;
|
||||
}
|
||||
PointerType pt = (PointerType)node.expr().type();
|
||||
checkMemberRef(pt.base(), node.name());
|
||||
}
|
||||
|
||||
protected void checkMemberRef(Type t, String memb) {
|
||||
if (! t.isComplexType()) {
|
||||
errorHandler.error("is not struct/union: " + t.textize());
|
||||
return;
|
||||
}
|
||||
ComplexType type = (ComplexType)t;
|
||||
if (! type.hasMember(memb)) {
|
||||
errorHandler.error(type.textize() +
|
||||
" does not have member " + memb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(DereferenceNode node) {
|
||||
super.visit(node);
|
||||
if (node.type().isPointer()) return;
|
||||
if (! node.expr().type().isPointer()) {
|
||||
notPointerError(node.type());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(AddressNode node) {
|
||||
|
|
|
@ -16,6 +16,10 @@ abstract public class ComplexType extends Type {
|
|||
isRecursiveChecked = false;
|
||||
}
|
||||
|
||||
public boolean isComplexType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
@ -31,6 +35,10 @@ abstract public class ComplexType extends Type {
|
|||
return members.iterator();
|
||||
}
|
||||
|
||||
public boolean hasMember(String name) {
|
||||
return (get(name) != null);
|
||||
}
|
||||
|
||||
public Type memberType(String name) {
|
||||
return fetch(name).type();
|
||||
}
|
||||
|
|
|
@ -9,69 +9,24 @@ public abstract class Type {
|
|||
|
||||
public abstract long size();
|
||||
|
||||
public boolean isReferable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVoid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isInt() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isInteger() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSigned() {
|
||||
throw new Error("#isSigned for non-integer type");
|
||||
}
|
||||
|
||||
public boolean isNumeric() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPointer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStruct() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUnion() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUserType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFunction() {
|
||||
return false;
|
||||
}
|
||||
public boolean isVoid() { return false; }
|
||||
public boolean isInt() { return false; }
|
||||
public boolean isInteger() { return false; }
|
||||
public boolean isSigned()
|
||||
{ throw new Error("#isSigned for non-integer type"); }
|
||||
public boolean isNumeric() { return false; }
|
||||
public boolean isPointer() { return false; }
|
||||
public boolean isArray() { return false; }
|
||||
public boolean isStruct() { return false; }
|
||||
public boolean isUnion() { return false; }
|
||||
public boolean isComplexType() { return false; }
|
||||
public boolean isUserType() { return false; }
|
||||
public boolean isFunction() { return false; }
|
||||
public boolean isCompatible(Type other) { return false; }
|
||||
public boolean isCastableTo(Type target) { return equals(target); }
|
||||
public boolean isReferable() { return false; }
|
||||
public boolean isCallable() { return false; }
|
||||
public boolean isIndexable() { return false; }
|
||||
|
||||
public abstract String textize();
|
||||
|
||||
public boolean isCompatible(Type other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCastableTo(Type target) {
|
||||
return equals(target);
|
||||
}
|
||||
|
||||
public boolean isCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isIndexable() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
struct a {
|
||||
int x;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct a s;
|
||||
s.x = 1;
|
||||
return s.nosuchmember;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
struct a {
|
||||
int x;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct a s;
|
||||
struct a *ptr = &s;
|
||||
ptr->x = 1;
|
||||
return ptr->nosuchmember;
|
||||
}
|
|
@ -122,12 +122,16 @@ assert_status 0 ./struct-semcheck
|
|||
assert_error $CBC struct-semcheck2.cb
|
||||
assert_error $CBC struct-semcheck3.cb
|
||||
assert_error $CBC struct-semcheck4.cb
|
||||
assert_error $CBC struct-semcheck5.cb
|
||||
assert_error $CBC struct-semcheck6.cb
|
||||
|
||||
assert_out "1;2;513" ./union # little endian
|
||||
assert_status 0 ./union-semcheck
|
||||
assert_error $CBC union-semcheck2.cb
|
||||
assert_error $CBC union-semcheck3.cb
|
||||
assert_error $CBC union-semcheck4.cb
|
||||
assert_error $CBC union-semcheck5.cb
|
||||
assert_error $CBC union-semcheck6.cb
|
||||
|
||||
assert_out "5;5" ./pointer
|
||||
assert_out "1;2" ./ptrmemb
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
union a {
|
||||
int x;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
union a u;
|
||||
u.x = 1;
|
||||
return u.nosuchmember;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
union a {
|
||||
int x;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
union a u;
|
||||
union a* ptr = &u;
|
||||
ptr->x = 1;
|
||||
return ptr->nosuchmember;
|
||||
}
|
Loading…
Reference in New Issue