Skip to content

Commit

Permalink
[CFE] Reproduction & fix of crashes found by weekly bot (#83)
Browse files Browse the repository at this point in the history
Calling "SpecialCasedBinaryOperator" and "SpecialCasedTernaryOperator"
with wrong number of parameters (especially too few) would not go well.
It's now checked and goes a lot better.

Change-Id: Id9606db869f020bbd7264686adaf9521bd263fb9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237900
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
  • Loading branch information
jensjoha authored and Commit Bot committed Mar 21, 2022
1 parent 04f8303 commit b6f03e1
Show file tree
Hide file tree
Showing 24 changed files with 275 additions and 14 deletions.
47 changes: 33 additions & 14 deletions pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2488,20 +2488,39 @@ class TypeInferrerImpl implements TypeInferrer {
namedIndex == arguments.named.length,
"Expected 'namedIndex' to be ${arguments.named.length}, "
"got ${namedIndex}.");
if (isSpecialCasedBinaryOperator) {
calleeType = replaceReturnType(
calleeType,
typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator(
receiverType!, actualTypes![0],
isNonNullableByDefault: isNonNullableByDefault));
} else if (isSpecialCasedTernaryOperator) {
calleeType = replaceReturnType(
calleeType,
typeSchemaEnvironment.getTypeOfSpecialCasedTernaryOperator(
receiverType!,
actualTypes![0],
actualTypes[1],
libraryBuilder.library));

if (isSpecialCasedBinaryOperator || isSpecialCasedTernaryOperator) {
if (typeChecksNeeded && !identical(calleeType, unknownFunction)) {
LocatedMessage? argMessage = helper!.checkArgumentsForType(
calleeType, arguments, offset,
isExtensionMemberInvocation: isExtensionMemberInvocation);
if (argMessage != null) {
return new WrapInProblemInferenceResult(
const InvalidType(),
const InvalidType(),
argMessage.messageObject,
argMessage.charOffset,
argMessage.length,
helper!,
isInapplicable: true,
hoistedArguments: localHoistedExpressions);
}
}
if (isSpecialCasedBinaryOperator) {
calleeType = replaceReturnType(
calleeType,
typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator(
receiverType!, actualTypes![0],
isNonNullableByDefault: isNonNullableByDefault));
} else if (isSpecialCasedTernaryOperator) {
calleeType = replaceReturnType(
calleeType,
typeSchemaEnvironment.getTypeOfSpecialCasedTernaryOperator(
receiverType!,
actualTypes![0],
actualTypes[1],
libraryBuilder.library));
}
}

// Check for and remove duplicated named arguments.
Expand Down
8 changes: 8 additions & 0 deletions pkg/front_end/test/fasta/expression_suite.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ import 'package:vm/target/vm.dart' show VmTarget;

import "package:yaml/yaml.dart" show YamlMap, YamlList, loadYamlNode;

import '../testing_utils.dart' show checkEnvironment;

import '../utils/kernel_chain.dart' show runDiff, openWrite;

class Context extends ChainContext {
Expand Down Expand Up @@ -568,6 +570,12 @@ class CompileExpression extends Step<List<TestCase>, List<TestCase>, Context> {

Future<Context> createContext(
Chain suite, Map<String, String> environment) async {
const Set<String> knownEnvironmentKeys = {
"updateExpectations",
"fuzz",
};
checkEnvironment(environment, knownEnvironmentKeys);

final Uri base = Uri.parse("org-dartlang-test:///");

/// Unused because we supply entry points to [computeDelta] directly above.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2022, 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.

sources: ""
definitions: []
position: "dart:core#double"
expression: |
remainder()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Errors: {
org-dartlang-debug:synthetic_debug_expression:1:10: Error: Too few positional arguments: 1 required, 0 given.
remainder()
^
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:10: Error: Too few positional arguments: 1 required, 0 given.\nremainder()\n ^" in this.{dart.core::double::remainder}{<inapplicable>}.(){() → invalid-type};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2022, 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.

sources: ""
definitions: []
position: "dart:core#double"
expression: |
clamp()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Errors: {
org-dartlang-debug:synthetic_debug_expression:1:6: Error: Too few positional arguments: 2 required, 0 given.
clamp()
^
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:6: Error: Too few positional arguments: 2 required, 0 given.\nclamp()\n ^" in this.{dart.core::num::clamp}{<inapplicable>}.(){() → invalid-type};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2022, 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.

sources: ""
definitions: []
position: "dart:core#double"
expression: |
clamp(42, 42)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return this.{dart.core::num::clamp}(42, 42){(dart.core::num, dart.core::num) → dart.core::num};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2022, 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.

sources: ""
definitions: []
position: "dart:core#double"
expression: |
remainder(42)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return this.{dart.core::double::remainder}(42){(dart.core::num) → dart.core::double};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
main2() {
double x = 42;
x.remainder();
}

main(List<String> args) {
if (args.length == 42) {
main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
main2() {}
main(List<String> args) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
main(List<String> args) {}
main2() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure.dart:3:14: Error: Too few positional arguments: 1 required, 0 given.
// x.remainder();
// ^
//
import self as self;
import "dart:core" as core;

static method main2() → dynamic {
core::double x = 42.0;
invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure.dart:3:14: Error: Too few positional arguments: 1 required, 0 given.
x.remainder();
^" in x.{core::double::remainder}{<inapplicable>}.(){() → invalid-type};
}
static method main(core::List<core::String> args) → dynamic {
if(args.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} 42) {
self::main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure.dart:3:14: Error: Too few positional arguments: 1 required, 0 given.
// x.remainder();
// ^
//
import self as self;
import "dart:core" as core;

static method main2() → dynamic {
core::double x = 42.0;
invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure.dart:3:14: Error: Too few positional arguments: 1 required, 0 given.
x.remainder();
^" in x.{core::double::remainder}{<inapplicable>}.(){() → invalid-type};
}
static method main(core::List<core::String> args) → dynamic {
if(args.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} 42) {
self::main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

static method main2() → dynamic
;
static method main(core::List<core::String> args) → dynamic
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure.dart:3:14: Error: Too few positional arguments: 1 required, 0 given.
// x.remainder();
// ^
//
import self as self;
import "dart:core" as core;

static method main2() → dynamic {
core::double x = 42.0;
invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure.dart:3:14: Error: Too few positional arguments: 1 required, 0 given.
x.remainder();
^" in x.{core::double::remainder}{<inapplicable>}.(){() → invalid-type};
}
static method main(core::List<core::String> args) → dynamic {
if(args.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} 42) {
self::main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
main2() {
double x = 42;
x.clamp();
}

main(List<String> args) {
if (args.length == 42) {
main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
main2() {}
main(List<String> args) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
main(List<String> args) {}
main2() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure_2.dart:3:10: Error: Too few positional arguments: 2 required, 0 given.
// x.clamp();
// ^
//
import self as self;
import "dart:core" as core;

static method main2() → dynamic {
core::double x = 42.0;
invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure_2.dart:3:10: Error: Too few positional arguments: 2 required, 0 given.
x.clamp();
^" in x.{core::num::clamp}{<inapplicable>}.(){() → invalid-type};
}
static method main(core::List<core::String> args) → dynamic {
if(args.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} 42) {
self::main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure_2.dart:3:10: Error: Too few positional arguments: 2 required, 0 given.
// x.clamp();
// ^
//
import self as self;
import "dart:core" as core;

static method main2() → dynamic {
core::double x = 42.0;
invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure_2.dart:3:10: Error: Too few positional arguments: 2 required, 0 given.
x.clamp();
^" in x.{core::num::clamp}{<inapplicable>}.(){() → invalid-type};
}
static method main(core::List<core::String> args) → dynamic {
if(args.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} 42) {
self::main2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

static method main2() → dynamic
;
static method main(core::List<core::String> args) → dynamic
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure_2.dart:3:10: Error: Too few positional arguments: 2 required, 0 given.
// x.clamp();
// ^
//
import self as self;
import "dart:core" as core;

static method main2() → dynamic {
core::double x = 42.0;
invalid-expression "pkg/front_end/testcases/general/error_recovery/weekly_bot_83_failure_2.dart:3:10: Error: Too few positional arguments: 2 required, 0 given.
x.clamp();
^" in x.{core::num::clamp}{<inapplicable>}.(){() → invalid-type};
}
static method main(core::List<core::String> args) → dynamic {
if(args.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} 42) {
self::main2();
}
}

0 comments on commit b6f03e1

Please sign in to comment.