From 8650017272dbbee98beafeea305cb6445d51130c Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 7 Feb 2025 15:50:20 -0800 Subject: [PATCH] Add and test new'ing an already-managed class type. Signed-off-by: Danila Fedorin --- frontend/lib/resolution/Resolver.cpp | 7 +++++++ frontend/test/resolution/testNew.cpp | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/frontend/lib/resolution/Resolver.cpp b/frontend/lib/resolution/Resolver.cpp index fd08c41ed302..d4f07ceae037 100644 --- a/frontend/lib/resolution/Resolver.cpp +++ b/frontend/lib/resolution/Resolver.cpp @@ -5402,6 +5402,13 @@ getDecoratedClassForNew(Context* context, const New* node, switch (node->management()) { case New::DEFAULT_MANAGEMENT: + // Management might've been provided for us already; otherwise + // fall back to the default: 'owned'. + if (!classType->decorator().isUnknownManagement()) + break; + + // Fall through to 'owned' management. + case New::OWNED: decorator = ClassTypeDecorator(ClassTypeDecorator::MANAGED); manager = AnyOwnedType::get(context); diff --git a/frontend/test/resolution/testNew.cpp b/frontend/test/resolution/testNew.cpp index aa416f7f39b4..664fb4d0fe6a 100644 --- a/frontend/test/resolution/testNew.cpp +++ b/frontend/test/resolution/testNew.cpp @@ -1040,6 +1040,23 @@ static void testUserGenericNew() { assert(guard.realizeErrors() == 1); } +static void testExplicitManagementNew() { + auto ctx = buildStdContext(); + ErrorGuard guard(ctx); + + auto var = resolveTypeOfXInit(ctx, + R"""( + class C{} + + proc getType() type do return unmanaged C; + + var x = new (getType())(); + )"""); + + assert(var.type()->isClassType()); + assert(var.type()->toClassType()->decorator().isUnmanaged()); +} + int main() { testEmptyRecordUserInit(); @@ -1056,6 +1073,7 @@ int main() { testCompilerGeneratedGenericNewClass(); testSimpleUserGenericNew(); testUserGenericNew(); + testExplicitManagementNew(); return 0; }