Fix typecheck crashes

We didn't fill in the m_namedEntity field for hiphop-only type
hints in non-hiphop mode, resulting in crashes when we tried to
use them.

Regardless of mode, we didn't check self or parent before
checking a non-object parameter, resulting in asserts in
dbg builds and seg-faults int opt builds.
Esse commit está contido em:
mwilliams
2013-06-22 09:20:57 -07:00
commit de Sara Golemon
commit fdc153980f
4 arquivos alterados com 21 adições e 8 exclusões
+6 -8
Ver Arquivo
@@ -72,7 +72,9 @@ void TypeConstraint::init() {
Type dtype;
TRACE(5, "TypeConstraint: this %p type %s, nullable %d\n",
this, typeName->data(), nullable());
if (!mapGet(s_typeNamesToTypes, typeName, &dtype)) {
if (!mapGet(s_typeNamesToTypes, typeName, &dtype) ||
!(hhType() || dtype.m_dt == KindOfArray || dtype.isParent() ||
dtype.isSelf())) {
TRACE(5, "TypeConstraint: this %p no such type %s, treating as object\n",
this, typeName->data());
m_type = { KindOfObject, Precise };
@@ -80,15 +82,11 @@ void TypeConstraint::init() {
TRACE(5, "TypeConstraint: NamedEntity: %p\n", m_namedEntity);
return;
}
if (hhType() || dtype.m_dt == KindOfArray || dtype.isParent() ||
dtype.isSelf()) {
m_type = dtype;
} else {
m_type = { KindOfObject, Precise };
}
m_type = dtype;
assert(m_type.m_dt != KindOfStaticString);
assert(IMPLIES(isParent(), m_type.m_dt == KindOfObject));
assert(IMPLIES(isSelf(), m_type.m_dt == KindOfObject));
assert(IMPLIES(isCallable(), m_type.m_dt == KindOfObject));
}
/*
@@ -186,7 +184,7 @@ TypeConstraint::check(const TypedValue* tv, const Func* func) const {
if (isCallable()) {
return f_is_callable(tvAsCVarRef(tv));
}
return checkTypedefNonObj(tv);
return isPrecise() && checkTypedefNonObj(tv);
}
return equivDataTypes(m_type.m_dt, tv->m_type);
+7
Ver Arquivo
@@ -56,6 +56,9 @@ protected:
constexpr bool isCallable() const {
return m_metatype == Callable;
}
constexpr bool isPrecise() const {
return m_metatype == Precise;
}
};
// m_type represents the DataType to check on. We don't know
@@ -109,6 +112,10 @@ public:
return m_type.isCallable();
}
bool isPrecise() const {
return m_type.isPrecise();
}
bool isObjectOrTypedef() const {
assert(IMPLIES(isParent(), m_type.m_dt == KindOfObject));
assert(IMPLIES(isSelf(), m_type.m_dt == KindOfObject));
+7
Ver Arquivo
@@ -0,0 +1,7 @@
<?php
class X {
function test(self $s) {
var_dump($s);
}
}
X::test("hello");
+1
Ver Arquivo
@@ -0,0 +1 @@
HipHop Fatal error: Argument 1 passed to X::test() must be an instance of X, string given in %s/test/quick/fail_self.php on line 5