diff --git a/TestSuite/errors/err0340_multiple_where.pas b/TestSuite/errors/err0340_multiple_where.pas new file mode 100644 index 000000000..14f74dc3a --- /dev/null +++ b/TestSuite/errors/err0340_multiple_where.pas @@ -0,0 +1,6 @@ +procedure p1(a: T1; b: T2); where T1, T2: record; +begin end; + +begin + p1(0, ''); +end. \ No newline at end of file diff --git a/TestSuite/errors/err0341_multiple_where.pas b/TestSuite/errors/err0341_multiple_where.pas new file mode 100644 index 000000000..8fef13f07 --- /dev/null +++ b/TestSuite/errors/err0341_multiple_where.pas @@ -0,0 +1,7 @@ +procedure p2(a: T1; b: T2; c: T3); where T1, T2: record; where T3: class; +begin + +end; +begin + p2(2, 4, 6); +end. \ No newline at end of file diff --git a/TestSuite/where10.pas b/TestSuite/where10.pas new file mode 100644 index 000000000..6335da21f --- /dev/null +++ b/TestSuite/where10.pas @@ -0,0 +1,19 @@ +procedure p1(a: T1; b: T2); where T1, T2: record; +begin + +end; +procedure p2(a: T1; b: T2; c: T3); where T1, T2: record; where T3: record; +begin + +end; +procedure p3(a: T1); where T1: record; +begin + +end; + +type Digits = (one, two); +begin + p1(0, 2); + p2(2, 4, 6); + p3(one); +end. \ No newline at end of file diff --git a/TestSuite/where8.pas b/TestSuite/where8.pas index 2dcfd08b8..eabc1ee5c 100644 --- a/TestSuite/where8.pas +++ b/TestSuite/where8.pas @@ -16,7 +16,7 @@ begin new t1(10) )); - Result.f0.Println; // до #1986 было AccessViolationException + assert(Result.f0 = 10); // до #1986 было AccessViolationException end; diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 200f01b19..25a4063c7 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -12356,25 +12356,28 @@ namespace PascalABCCompiler.TreeConverter List used_types = new List(where_list.defs.Count); foreach (SyntaxTree.where_definition wd in where_list.defs) { - bool param_not_found = true; - foreach (common_type_node param in gparams) + foreach (SyntaxTree.ident wd_id in wd.names.idents) { - if (String.Equals(param.name, wd.names.idents[0].name, StringComparison.InvariantCultureIgnoreCase)) + bool param_not_found = true; + foreach (common_type_node param in gparams) { - //Нашли нужный шаблонный параметр - if (used_types.Contains(param)) + if (String.Equals(param.name, wd_id.name, StringComparison.InvariantCultureIgnoreCase)) { - AddError(get_location(wd.names), "SPECIFICATORS_FOR_{0}_ALREADY_EXIST", wd.names.idents[0].name); + //Нашли нужный шаблонный параметр + if (used_types.Contains(param)) + { + AddError(get_location(wd.names), "SPECIFICATORS_FOR_{0}_ALREADY_EXIST", wd_id.name); + } + add_generic_eliminations(param, wd.types.defs); + used_types.Add(param); + param_not_found = false; + break; } - add_generic_eliminations(param, wd.types.defs); - used_types.Add(param); - param_not_found = false; - break; } - } - if (param_not_found) - { - AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names))); + if (param_not_found) + { + AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names))); + } } } context.EndSkipGenericInstanceChecking(); diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index ff7e63306..7a859480c 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -141,11 +141,13 @@ namespace PascalABCCompiler.TreeRealization public static CompilationErrorWithLocation check_type_list(List tparams, List gpe_list, bool method_param_types, out int i) { int count = tparams.Count; + for (i = 0; i < count; i++) { generic_parameter_eliminations gpe = gpe_list[i]; type_node tn = tparams[i]; - if (gpe.is_class && !tn.is_class && !(tn.base_type != null && tn.base_type.is_class)) + + if (gpe.is_class && !tn.is_class && !(tn.is_generic_parameter && tn.base_type != null && tn.base_type.is_class)) { return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_REFERENCE_TYPE", tn.PrintableName); }