Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Unified Diff: runtime/vm/class_finalizer.cc

Issue 66033006: Check type bounds of redirecting factories (issue 14699). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 30176)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -289,6 +289,10 @@
if (type.IsMalformed()) {
ReportError(Error::Handle(type.malformed_error()));
}
+ Error& error = Error::Handle();
+ if (type.IsMalboundedWithError(&error)) {
+ ReportError(error);
+ }
}
}
}
@@ -316,8 +320,8 @@
// Check if target is already resolved.
Type& type = Type::Handle(factory.RedirectionType());
Function& target = Function::Handle(factory.RedirectionTarget());
- if (type.IsMalformed()) {
- // Already resolved to a malformed type. Will throw on usage.
+ if (type.IsMalformed() || (type.IsResolved() && type.IsMalbounded())) {
+ // Already resolved to a malformed or malbounded type. Will throw on usage.
ASSERT(target.IsNull());
return;
}
@@ -334,7 +338,7 @@
ResolveType(cls, type, kCanonicalize);
type ^= FinalizeType(cls, type, kCanonicalize);
factory.SetRedirectionType(type);
- if (type.IsMalformed()) {
+ if (type.IsMalformed() || type.IsMalbounded()) {
ASSERT(factory.RedirectionTarget() == Function::null());
return;
}
@@ -430,13 +434,14 @@
if (!target_type.IsInstantiated()) {
const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
type.arguments());
- Error& malformed_error = Error::Handle();
- target_type ^= target_type.InstantiateFrom(type_args, &malformed_error);
- if (malformed_error.IsNull()) {
+ Error& bound_error = Error::Handle();
+ target_type ^= target_type.InstantiateFrom(type_args, &bound_error);
+ if (bound_error.IsNull()) {
target_type ^= FinalizeType(cls, target_type, kCanonicalize);
} else {
+ ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated());
const Script& script = Script::Handle(target_class.script());
- FinalizeMalformedType(malformed_error, script, target_type,
+ FinalizeMalformedType(bound_error, script, target_type,
"cannot resolve redirecting factory");
target_target = Function::null();
}
@@ -596,14 +601,16 @@
if (!super_type_args.IsNull()) {
super_type_arg = super_type_args.TypeAt(super_offset + i);
if (!super_type_arg.IsInstantiated()) {
- Error& malformed_error = Error::Handle();
- super_type_arg = super_type_arg.InstantiateFrom(arguments,
- &malformed_error);
- if (!malformed_error.IsNull()) {
- if (!super_type_arg.IsInstantiated()) {
- // CheckTypeArgumentBounds will insert a BoundedType.
- } else if (bound_error->IsNull()) {
- *bound_error = malformed_error.raw();
+ Error& error = Error::Handle();
+ super_type_arg = super_type_arg.InstantiateFrom(arguments, &error);
+ if (!error.IsNull()) {
+ // InstantiateFrom does not report an error if the type is still
+ // uninstantiated. Instead, it will return a new BoundedType so that
+ // the check is postponed to run time.
+ ASSERT(super_type_arg.IsInstantiated());
+ // Keep only the first bound error.
+ if (bound_error->IsNull()) {
+ *bound_error = error.raw();
}
}
}
@@ -665,14 +672,13 @@
type_param.set_bound(declared_bound);
}
ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized());
- Error& malformed_error = Error::Handle();
+ Error& error = Error::Handle();
// Note that the bound may be malformed, in which case the bound check
// will return an error and the bound check will be postponed to run time.
if (declared_bound.IsInstantiated()) {
instantiated_bound = declared_bound.raw();
} else {
- instantiated_bound =
- declared_bound.InstantiateFrom(arguments, &malformed_error);
+ instantiated_bound = declared_bound.InstantiateFrom(arguments, &error);
}
if (!instantiated_bound.IsFinalized()) {
// The bound refers to type parameters, creating a cycle; postpone
@@ -684,35 +690,21 @@
arguments.SetTypeAt(offset + i, type_arg);
continue;
}
- // TODO(regis): We could simplify this code if we could differentiate
- // between a failed bound check and a bound check that is undecidable at
- // compile time.
// Shortcut the special case where we check a type parameter against its
// declared upper bound.
- bool below_bound = true;
- if (malformed_error.IsNull() &&
- (!type_arg.Equals(type_param) ||
- !instantiated_bound.Equals(declared_bound))) {
- // Pass NULL to prevent expensive and unnecessary error formatting in
- // the case the bound check is postponed to run time.
- below_bound = type_param.CheckBound(type_arg, instantiated_bound, NULL);
- }
- if (!malformed_error.IsNull() || !below_bound) {
- if (!type_arg.IsInstantiated() ||
- !instantiated_bound.IsInstantiated()) {
+ if (error.IsNull() &&
+ !(type_arg.Equals(type_param) &&
+ instantiated_bound.Equals(declared_bound))) {
+ if (!type_param.CheckBound(type_arg, instantiated_bound, &error) &&
+ error.IsNull()) {
+ // The bound cannot be checked at compile time; postpone to run time.
type_arg = BoundedType::New(type_arg, instantiated_bound, type_param);
arguments.SetTypeAt(offset + i, type_arg);
- } else if (bound_error->IsNull()) {
- if (malformed_error.IsNull()) {
- // Call CheckBound again to format error message.
- type_param.CheckBound(type_arg,
- instantiated_bound,
- &malformed_error);
- }
- ASSERT(!malformed_error.IsNull());
- *bound_error = malformed_error.raw();
}
}
+ if (!error.IsNull() && bound_error->IsNull()) {
+ *bound_error = error.raw();
+ }
}
}
AbstractType& super_type = AbstractType::Handle(cls.super_type());
« no previous file with comments | « runtime/vm/ast.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698