Commit e4d91e36 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix a type analysis bug

A discrepancy between irgen and type_analysis was causing an assertion.  The
difference was that irgen will do full type inference for things that get put
into closures (ie in the parent scope), but type_analysis was bailing and
just saying that it was unknown.
parent fd4737aa
......@@ -33,7 +33,7 @@
#include "runtime/types.h"
//#undef VERBOSITY
//#define VERBOSITY(x) 2
//#define VERBOSITY(x) 4
namespace pyston {
......@@ -116,9 +116,11 @@ private:
if (speculated_cls != NULL && speculated_cls->is_constant) {
ConcreteCompilerType* speculated_type = unboxedType(typeFromClass(speculated_cls));
if (VERBOSITY() >= 2) {
printf("in propagator, speculating that %s would actually be %s, at:\n", old_type->debugName().c_str(),
printf("in propagator, speculating that %s would actually be %s, at ", old_type->debugName().c_str(),
speculated_type->debugName().c_str());
fflush(stdout);
print_ast(node);
llvm::outs().flush();
printf("\n");
}
......@@ -152,8 +154,9 @@ private:
CompilerType* rtn = static_cast<CompilerType*>(raw_rtn);
if (VERBOSITY() >= 3) {
printf("Type of ");
print_ast(node);
printf(" %s\n", rtn->debugName().c_str());
printf(" is %s\n", rtn->debugName().c_str());
}
expr_types[node] = rtn;
......@@ -428,10 +431,6 @@ private:
return UNKNOWN;
}
if (name_scope == ScopeInfo::VarScopeType::CLOSURE) {
return UNKNOWN;
}
if (name_scope == ScopeInfo::VarScopeType::NAME) {
return UNKNOWN;
}
......@@ -440,7 +439,7 @@ private:
return UNKNOWN;
}
if (name_scope == ScopeInfo::VarScopeType::FAST) {
if (name_scope == ScopeInfo::VarScopeType::FAST || name_scope == ScopeInfo::VarScopeType::CLOSURE) {
CompilerType*& t = sym_table[node->id];
if (t == NULL) {
// if (VERBOSITY() >= 2) {
......
......@@ -1170,7 +1170,7 @@ private:
llvm::Value* r = emitter.createCall3(unw_info, g.funcs.boxedLocalsGet, boxedLocals, attr, module);
return new ConcreteCompilerVariable(UNKNOWN, r, true);
} else {
// vst is one of {FAST, CLOSURE, NAME}
// vst is one of {FAST, CLOSURE}
if (symbol_table.find(node->id) == symbol_table.end()) {
// TODO should mark as DEAD here, though we won't end up setting all the names appropriately
// state = DEAD;
......@@ -1541,14 +1541,24 @@ private:
if (VERBOSITY("irgen") >= 2) {
printf("Speculating that %s is actually %s, at ", rtn->getConcreteType()->debugName().c_str(),
speculated_type->debugName().c_str());
PrintVisitor printer;
node->accept(&printer);
fflush(stdout);
print_ast(node);
llvm::outs().flush();
printf("\n");
}
#ifndef NDEBUG
// That's not really a speculation.... could potentially handle this here, but
// I think it's better to just not generate bad speculations:
assert(!rtn->canConvertTo(speculated_type));
if (rtn->canConvertTo(speculated_type)) {
auto source = irstate->getSourceInfo();
printf("On %s:%d, function %s:\n", source->getFn()->c_str(), source->body[0]->lineno,
source->getName()->c_str());
irstate->getSourceInfo()->cfg->print();
}
RELEASE_ASSERT(!rtn->canConvertTo(speculated_type), "%s %s", rtn->getType()->debugName().c_str(),
speculated_type->debugName().c_str());
#endif
ConcreteCompilerVariable* old_rtn = rtn->makeConverted(emitter, UNKNOWN);
rtn->decvref(emitter);
......
......@@ -243,7 +243,7 @@ public:
if (!lookup_success) {
llvm::Constant* int_val
= llvm::ConstantInt::get(g.i64, reinterpret_cast<uintptr_t>(addr), false);
llvm::Constant* ptr_val = llvm::ConstantExpr::getIntToPtr(int_val, g.i8);
llvm::Constant* ptr_val = llvm::ConstantExpr::getIntToPtr(int_val, g.i8_ptr);
ii->setArgOperand(i, ptr_val);
continue;
} else {
......
......@@ -1056,6 +1056,7 @@ void* AST_MakeClass::accept_expr(ExprVisitor* v) {
void print_ast(AST* ast) {
PrintVisitor v;
ast->accept(&v);
v.flush();
}
void PrintVisitor::printIndent() {
......
......@@ -1338,6 +1338,9 @@ private:
public:
PrintVisitor(int indent = 0, llvm::raw_ostream& stream = llvm::outs()) : stream(stream), indent(indent) {}
virtual ~PrintVisitor() {}
void flush() {
stream.flush();
}
virtual bool visit_alias(AST_alias* node);
virtual bool visit_arguments(AST_arguments* node);
......
......@@ -82,3 +82,15 @@ def f7(n):
c = f7(5)()
print c.foo()
# Regression test: being included in a closure (ie in the parent scope) shouldn't ruin type analysis.
def f8():
l = []
def g():
print l
l.append(1)
for i in xrange(11000):
f8()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment