Commit 4a7bcfbb authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix a codegen bug

If we could statically determine that an object doesn't have a __nonzero__ method,
we would previously say that it had an undefined truth value (and then crash).
parent ba5d093c
......@@ -1578,9 +1578,16 @@ public:
ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override {
static const std::string attr("__nonzero__");
bool no_attribute = false;
ConcreteCompilerVariable* called_constant
= tryCallattrConstant(emitter, info, var, &attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL);
if (called_constant)
= tryCallattrConstant(emitter, info, var, &attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL, &no_attribute);
// TODO: if no_attribute, we could optimize by continuing the dispatch process and trying
// to call __len__ (and if that doesn't exist, returning a static true).
// For now, I'd rather not duplicate the dispatch behavior between here and objmodel.cpp::nonzero.
if (called_constant && !no_attribute)
return called_constant;
if (cls == bool_cls) {
......
# In certain cases, we can statically-determine that a variable is truthy.
# In the past, we would crash in irgen because of this, so for now this is just
# a crash test.
def f(x):
print hasattr(x, "__nonzero__")
if x:
print "true"
# Objects without nonzero methods that are still true:
f(file)
f(open("/dev/null"))
f(Exception())
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