[cfe] Use correct library when building origin outline expressions

When constructors are synthesized for mixin applications, the default
values and initializers of the original constructor needs to be copied
over for const constructors. Since the original default values and
initializers may not have been created yet, when these are required
for the synthesized constructor, the synthesized constructor triggers
the computation on the original constructor. This triggering wrongly
used the library of the synthesized constructor and not the original
constructor as the context for this computation, thus not handling
privacy correctly.

Closes #46581

Change-Id: If0c5129427c7e7c8d6434bbaa96b4df559dccc85
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206200
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Johnni Winther 2021-07-08 13:49:04 +00:00 committed by commit-bot@chromium.org
parent 6facd6dfda
commit f36c55501a
17 changed files with 303 additions and 3 deletions

View file

@ -1135,7 +1135,9 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
}
if (instanceClass != null) {
for (Constructor constructor in instanceClass.constructors) {
if (constructor.name == name) return constructor;
if (constructor.name == name) {
return constructor;
}
}
}

View file

@ -7,6 +7,8 @@ import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import '../builder/library_builder.dart';
import '../constant_context.dart' show ConstantContext;
import '../dill/dill_member_builder.dart';
@ -484,8 +486,13 @@ class SyntheticConstructorBuilder extends DillConstructorBuilder {
List<DelayedActionPerformer> delayedActionPerformers) {
if (_origin != null) {
// Ensure that default value expressions have been created for [_origin].
_origin!.buildOutlineExpressions(
libraryBuilder, coreTypes, delayedActionPerformers);
LibraryBuilder originLibraryBuilder = _origin!.library;
if (originLibraryBuilder is SourceLibraryBuilder) {
// If [_origin] is from a source library, we need to build the default
// values and initializers first.
_origin!.buildOutlineExpressions(
originLibraryBuilder, coreTypes, delayedActionPerformers);
}
_clonedFunctionNode!.cloneDefaultValues();
_clonedFunctionNode = null;
_origin = null;

View file

@ -0,0 +1,13 @@
// Copyright (c) 2021, 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.
import 'issue46581_lib.dart';
class TestClass extends MyClass with MyMixin {
TestClass() : super.named();
}
mixin MyMixin {}
void main() {}

View file

@ -0,0 +1,8 @@
import 'issue46581_lib.dart';
class TestClass extends MyClass with MyMixin {
TestClass() : super.named();
}
mixin MyMixin {}
void main() {}

View file

@ -0,0 +1,8 @@
import 'issue46581_lib.dart';
class TestClass extends MyClass with MyMixin {
TestClass() : super.named();
}
mixin MyMixin {}
void main() {}

View file

@ -0,0 +1,36 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue46581_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue46581_lib.dart";
abstract class _TestClass&MyClass&MyMixin = iss::MyClass with self::MyMixin /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor _() → self::_TestClass&MyClass&MyMixin
: super iss::MyClass::_()
;
const synthetic constructor named() → self::_TestClass&MyClass&MyMixin
: super iss::MyClass::named()
;
}
class TestClass extends self::_TestClass&MyClass&MyMixin {
constructor •() → self::TestClass
: super self::_TestClass&MyClass&MyMixin::named()
;
}
abstract class MyMixin extends core::Object /*isMixinDeclaration*/ {
}
static method main() → void {}
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
class MyClass extends core::Object /*hasConstConstructor*/ {
const constructor _() → iss::MyClass
: super core::Object::•()
;
const constructor named() → iss::MyClass
: this iss::MyClass::_()
;
}

View file

@ -0,0 +1,36 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue46581_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue46581_lib.dart";
abstract class _TestClass&MyClass&MyMixin = iss::MyClass with self::MyMixin /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor _() → self::_TestClass&MyClass&MyMixin
: super iss::MyClass::_()
;
const synthetic constructor named() → self::_TestClass&MyClass&MyMixin
: super iss::MyClass::named()
;
}
class TestClass extends self::_TestClass&MyClass&MyMixin {
constructor •() → self::TestClass
;
}
abstract class MyMixin extends core::Object /*isMixinDeclaration*/ {
}
static method main() → void
;
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
class MyClass extends core::Object /*hasConstConstructor*/ {
const constructor _() → iss::MyClass
: super core::Object::•()
;
const constructor named() → iss::MyClass
: this iss::MyClass::_()
;
}

View file

@ -0,0 +1,36 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue46581_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue46581_lib.dart";
abstract class _TestClass&MyClass&MyMixin extends iss::MyClass implements self::MyMixin /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
const synthetic constructor _() → self::_TestClass&MyClass&MyMixin
: super iss::MyClass::_()
;
const synthetic constructor named() → self::_TestClass&MyClass&MyMixin
: super iss::MyClass::named()
;
}
class TestClass extends self::_TestClass&MyClass&MyMixin {
constructor •() → self::TestClass
: super self::_TestClass&MyClass&MyMixin::named()
;
}
abstract class MyMixin extends core::Object /*isMixinDeclaration*/ {
}
static method main() → void {}
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
class MyClass extends core::Object /*hasConstConstructor*/ {
const constructor _() → iss::MyClass
: super core::Object::•()
;
const constructor named() → iss::MyClass
: this iss::MyClass::_()
;
}

View file

@ -0,0 +1,13 @@
// Copyright (c) 2021, 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.
import 'main_lib.dart';
class TestClass extends MyClass with MyMixin {
TestClass() : super.named();
}
mixin MyMixin {}
void main() {}

View file

@ -0,0 +1,8 @@
import 'main_lib.dart';
class TestClass extends MyClass with MyMixin {
TestClass() : super.named();
}
mixin MyMixin {}
void main() {}

View file

@ -0,0 +1,8 @@
import 'main_lib.dart';
class TestClass extends MyClass with MyMixin {
TestClass() : super.named();
}
mixin MyMixin {}
void main() {}

View file

@ -0,0 +1,36 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
abstract class _TestClass&MyClass&MyMixin = mai::MyClass with self::MyMixin /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor _() → self::_TestClass&MyClass&MyMixin
: super mai::MyClass::_()
;
const synthetic constructor named() → self::_TestClass&MyClass&MyMixin
: super mai::MyClass::named()
;
}
class TestClass extends self::_TestClass&MyClass&MyMixin {
constructor •() → self::TestClass
: super self::_TestClass&MyClass&MyMixin::named()
;
}
abstract class MyMixin extends core::Object /*isMixinDeclaration*/ {
}
static method main() → void {}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
class MyClass extends core::Object /*hasConstConstructor*/ {
const constructor _() → mai::MyClass
: super core::Object::•()
;
const constructor named() → mai::MyClass
: this mai::MyClass::_()
;
}

View file

@ -0,0 +1,36 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
abstract class _TestClass&MyClass&MyMixin = mai::MyClass with self::MyMixin /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor _() → self::_TestClass&MyClass&MyMixin
: super mai::MyClass::_()
;
const synthetic constructor named() → self::_TestClass&MyClass&MyMixin
: super mai::MyClass::named()
;
}
class TestClass extends self::_TestClass&MyClass&MyMixin {
constructor •() → self::TestClass
;
}
abstract class MyMixin extends core::Object /*isMixinDeclaration*/ {
}
static method main() → void
;
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
class MyClass extends core::Object /*hasConstConstructor*/ {
const constructor _() → mai::MyClass
: super core::Object::•()
;
const constructor named() → mai::MyClass
: this mai::MyClass::_()
;
}

View file

@ -0,0 +1,36 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
abstract class _TestClass&MyClass&MyMixin extends mai::MyClass implements self::MyMixin /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
const synthetic constructor _() → self::_TestClass&MyClass&MyMixin
: super mai::MyClass::_()
;
const synthetic constructor named() → self::_TestClass&MyClass&MyMixin
: super mai::MyClass::named()
;
}
class TestClass extends self::_TestClass&MyClass&MyMixin {
constructor •() → self::TestClass
: super self::_TestClass&MyClass&MyMixin::named()
;
}
abstract class MyMixin extends core::Object /*isMixinDeclaration*/ {
}
static method main() → void {}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
class MyClass extends core::Object /*hasConstConstructor*/ {
const constructor _() → mai::MyClass
: super core::Object::•()
;
const constructor named() → mai::MyClass
: this mai::MyClass::_()
;
}

View file

@ -0,0 +1,8 @@
// Copyright (c) 2021, 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.
class MyClass {
const MyClass._();
const MyClass.named() : this._();
}

View file

@ -0,0 +1 @@
main_lib.dart

View file

@ -0,0 +1,8 @@
// Copyright (c) 2021, 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.
class MyClass {
const MyClass._();
const MyClass.named() : this._();
}