mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 17:24:54 +00:00
Implement more restrictive checking of typedefs illegally referring to
themselves and fix vm issue 9611. Update a test and add a test. R=srdjan@google.com Review URL: https://codereview.chromium.org//19997003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25382 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
aaf9f61a80
commit
7b9a84dfbb
|
@ -1663,6 +1663,36 @@ bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
|
|||
}
|
||||
|
||||
|
||||
// Helper function called by IsAliasCycleFree.
|
||||
bool ClassFinalizer::IsParameterTypeCycleFree(
|
||||
const Class& cls,
|
||||
const AbstractType& type,
|
||||
GrowableArray<intptr_t>* visited) {
|
||||
ASSERT(visited != NULL);
|
||||
ResolveType(cls, type, kCanonicalize);
|
||||
if (type.IsType() && !type.IsMalformed()) {
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
if (!type_class.is_type_finalized() &&
|
||||
type_class.IsSignatureClass() &&
|
||||
!IsAliasCycleFree(type_class, visited)) {
|
||||
return false;
|
||||
}
|
||||
const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
|
||||
type.arguments());
|
||||
if (!type_args.IsNull()) {
|
||||
AbstractType& type_arg = AbstractType::Handle();
|
||||
for (intptr_t i = 0; i < type_args.Length(); i++) {
|
||||
type_arg = type_args.TypeAt(i);
|
||||
if (!IsParameterTypeCycleFree(cls, type_arg, visited)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Returns false if the function type alias illegally refers to itself.
|
||||
bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
|
||||
GrowableArray<intptr_t>* visited) {
|
||||
|
@ -1682,27 +1712,15 @@ bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
|
|||
const Function& function = Function::Handle(cls.signature_function());
|
||||
// Check class of result type.
|
||||
AbstractType& type = AbstractType::Handle(function.result_type());
|
||||
ResolveType(cls, type, kCanonicalize);
|
||||
if (type.IsType() && !type.IsMalformed()) {
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
if (!type_class.is_type_finalized() &&
|
||||
type_class.IsSignatureClass() &&
|
||||
!IsAliasCycleFree(type_class, visited)) {
|
||||
return false;
|
||||
}
|
||||
if (!IsParameterTypeCycleFree(cls, type, visited)) {
|
||||
return false;
|
||||
}
|
||||
// Check classes of formal parameter types.
|
||||
const intptr_t num_parameters = function.NumParameters();
|
||||
for (intptr_t i = 0; i < num_parameters; i++) {
|
||||
type = function.ParameterTypeAt(i);
|
||||
ResolveType(cls, type, kCanonicalize);
|
||||
if (type.IsType() && !type.IsMalformed()) {
|
||||
const Class& type_class = Class::Handle(type.type_class());
|
||||
if (!type_class.is_type_finalized() &&
|
||||
type_class.IsSignatureClass() &&
|
||||
!IsAliasCycleFree(type_class, visited)) {
|
||||
return false;
|
||||
}
|
||||
if (!IsParameterTypeCycleFree(cls, type, visited)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
visited->RemoveLast();
|
||||
|
|
|
@ -93,6 +93,9 @@ class ClassFinalizer : public AllStatic {
|
|||
|
||||
private:
|
||||
static bool IsSuperCycleFree(const Class& cls);
|
||||
static bool IsParameterTypeCycleFree(const Class& cls,
|
||||
const AbstractType& type,
|
||||
GrowableArray<intptr_t>* visited);
|
||||
static bool IsAliasCycleFree(const Class& cls,
|
||||
GrowableArray<intptr_t>* visited);
|
||||
static void CheckForLegalConstClass(const Class& cls);
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
typedef F(List<F> x);
|
||||
typedef F(List
|
||||
<F> /// 00: compile-time error
|
||||
x);
|
||||
|
||||
typedef D C();
|
||||
|
||||
|
|
14
tests/language/function_type_alias9_test.dart
Normal file
14
tests/language/function_type_alias9_test.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
// Dart test for legally self referencing function type alias.
|
||||
|
||||
typedef void F(List
|
||||
<G> /// 00: compile-time error
|
||||
l);
|
||||
typedef void G(List<F> l);
|
||||
|
||||
main() {
|
||||
F foo(G g) => g;
|
||||
foo(null);
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
[ $compiler == dart2dart ]
|
||||
mixin_super_constructor_named_test: Fail
|
||||
mixin_super_constructor_positionals_test: Fail
|
||||
function_type_alias6_test/00: Fail # Issue 11986
|
||||
function_type_alias9_test/00: Crash # Issue 11986
|
||||
|
||||
[ $compiler == none ]
|
||||
mixin_super_constructor_named_test: Fail
|
||||
|
|
|
@ -119,6 +119,8 @@ default_implementation2_test: fail
|
|||
f_bounded_quantification_test/01: fail
|
||||
f_bounded_quantification_test/02: fail
|
||||
|
||||
function_type_alias6_test/00: fail # Issue 11987
|
||||
function_type_alias9_test/00: crash # Issue 11987
|
||||
named_parameters_aggregated_test/03: fail
|
||||
no_such_method_negative_test: fail
|
||||
non_const_super_negative_test: fail
|
||||
|
|
|
@ -90,7 +90,8 @@ compile_time_constant_checked3_test/05: Fail, OK
|
|||
compile_time_constant_checked3_test/06: Fail, OK
|
||||
|
||||
[ $compiler == dart2js ]
|
||||
function_type_alias6_test: Crash # dartbug.com/9792
|
||||
function_type_alias6_test/00: Crash # dartbug.com/9792
|
||||
function_type_alias9_test/00: Crash # dartbug.com/9792
|
||||
branch_canonicalization_test: Fail # Issue 638.
|
||||
div_with_power_of_two_test: Fail # Issue 8301.
|
||||
class_literal_test: Fail # Issue 7626.
|
||||
|
|
Loading…
Reference in a new issue