Skip to content

Commit 6d246de

Browse files
authored
Merge pull request #69205 from kubamracek/embedded-diagnose-thick-metatypes
[embedded] Start diagnosing metatype/value_metatype instructions in embedded Swift
2 parents b55a304 + a026b38 commit 6d246de

File tree

5 files changed

+90
-15
lines changed

5 files changed

+90
-15
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,10 @@ ERROR(embedded_swift_existential_type,none,
356356
"cannot use a value of protocol type %0 in embedded Swift", (Type))
357357
ERROR(embedded_swift_existential,none,
358358
"cannot use a value of protocol type in embedded Swift", ())
359+
ERROR(embedded_swift_metatype_type,none,
360+
"cannot use metatype of type %0 in embedded Swift", (Type))
361+
ERROR(embedded_swift_metatype,none,
362+
"cannot use metatype in embedded Swift", ())
359363
NOTE(performance_called_from,none,
360364
"called from here", ())
361365

lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ bool PerformanceDiagnostics::visitFunction(SILFunction *function,
163163
continue;
164164

165165
for (SILInstruction &inst : block) {
166-
if (visitInst(&inst, perfConstr, parentLoc))
166+
if (visitInst(&inst, perfConstr, parentLoc)) {
167+
LLVM_DEBUG(llvm::dbgs() << inst << *inst.getFunction());
167168
return true;
169+
}
168170

169171
if (auto as = FullApplySite::isa(&inst)) {
170172
if (isEffectFreeArraySemanticCall(&inst))
@@ -346,22 +348,51 @@ static bool metatypeUsesAreNotRelevant(MetatypeInst *mt) {
346348
return true;
347349
}
348350

351+
static bool allowedMetadataUseInEmbeddedSwift(SILInstruction *inst) {
352+
// Only diagnose metatype and value_metatype instructions, for now.
353+
if ((isa<ValueMetatypeInst>(inst) || isa<MetatypeInst>(inst))) {
354+
auto metaTy = cast<SingleValueInstruction>(inst)->getType().castTo<MetatypeType>();
355+
if (metaTy->getRepresentation() == MetatypeRepresentation::Thick) {
356+
Type instTy = metaTy->getInstanceType();
357+
if (auto selfType = instTy->getAs<DynamicSelfType>())
358+
instTy = selfType->getSelfType();
359+
// Class metadata are supported in embedded Swift
360+
return instTy->getClassOrBoundGenericClass() ? true : false;
361+
}
362+
}
363+
364+
return true;
365+
}
366+
349367
bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
350368
PerformanceConstraints perfConstr,
351369
LocWithParent *parentLoc) {
352370
SILType impactType;
353371
RuntimeEffect impact = getRuntimeEffect(inst, impactType);
354372
LocWithParent loc(inst->getLoc().getSourceLoc(), parentLoc);
355373

356-
if (module.getOptions().EmbeddedSwift &&
357-
impact & RuntimeEffect::Existential) {
358-
PrettyStackTracePerformanceDiagnostics stackTrace("existential", inst);
359-
if (impactType) {
360-
diagnose(loc, diag::embedded_swift_existential_type, impactType.getASTType());
361-
} else {
362-
diagnose(loc, diag::embedded_swift_existential);
374+
if (module.getOptions().EmbeddedSwift) {
375+
if (impact & RuntimeEffect::Existential) {
376+
PrettyStackTracePerformanceDiagnostics stackTrace("existential", inst);
377+
if (impactType) {
378+
diagnose(loc, diag::embedded_swift_existential_type, impactType.getASTType());
379+
} else {
380+
diagnose(loc, diag::embedded_swift_existential);
381+
}
382+
return true;
383+
}
384+
385+
if (impact & RuntimeEffect::MetaData) {
386+
if (!allowedMetadataUseInEmbeddedSwift(inst)) {
387+
PrettyStackTracePerformanceDiagnostics stackTrace("metatype", inst);
388+
if (impactType) {
389+
diagnose(loc, diag::embedded_swift_metatype_type, impactType.getASTType());
390+
} else {
391+
diagnose(loc, diag::embedded_swift_metatype);
392+
}
393+
return true;
394+
}
363395
}
364-
return true;
365396
}
366397

367398
if (perfConstr == PerformanceConstraints::None)
@@ -512,7 +543,9 @@ void PerformanceDiagnostics::checkNonAnnotatedFunction(SILFunction *function) {
512543
for (SILInstruction &inst : block) {
513544
if (function->getModule().getOptions().EmbeddedSwift) {
514545
auto loc = LocWithParent(inst.getLoc().getSourceLoc(), nullptr);
515-
visitInst(&inst, PerformanceConstraints::None, &loc);
546+
if (visitInst(&inst, PerformanceConstraints::None, &loc)) {
547+
LLVM_DEBUG(llvm::dbgs() << inst << *inst.getFunction());
548+
}
516549
}
517550

518551
auto as = FullApplySite::isa(&inst);

stdlib/public/core/ContiguousArrayBuffer.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,13 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
302302
self = _ContiguousArrayBuffer<Element>()
303303
}
304304
else {
305-
let storageType: _ContiguousArrayStorage<Element>.Type
306305
#if !$Embedded
307-
storageType = getContiguousArrayStorageType(for: Element.self)
306+
_storage = Builtin.allocWithTailElems_1(
307+
getContiguousArrayStorageType(for: Element.self), realMinimumCapacity._builtinWordValue, Element.self)
308308
#else
309-
storageType = _ContiguousArrayStorage<Element>.self
310-
#endif
311309
_storage = Builtin.allocWithTailElems_1(
312-
storageType, realMinimumCapacity._builtinWordValue, Element.self)
310+
_ContiguousArrayStorage<Element>.self, realMinimumCapacity._builtinWordValue, Element.self)
311+
#endif
313312

314313
let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(_storage))
315314
let allocSize: Int?

test/embedded/metatypes.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-emit-ir -verify %s -enable-experimental-feature Embedded -wmo
2+
3+
// REQUIRES: optimized_stdlib
4+
// REQUIRES: VENDOR=apple
5+
// REQUIRES: OS=macosx
6+
7+
public func sink<T>(t: T) {}
8+
9+
public func test() -> Int {
10+
let metatype = Int.self
11+
sink(t: metatype) // expected-error {{cannot use metatype of type 'Int' in embedded Swift}}
12+
// expected-note@-1 {{called from here}}
13+
return 42
14+
}

test/embedded/typeof.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-emit-ir -verify %s -enable-experimental-feature Embedded -wmo
2+
3+
// REQUIRES: optimized_stdlib
4+
// REQUIRES: VENDOR=apple
5+
// REQUIRES: OS=macosx
6+
7+
public func unsafeWriteArray<T, R>(_ elementType: R.Type, array: inout T, index n: Int, value: R) {
8+
precondition(_isPOD(elementType))
9+
precondition(_isPOD(type(of: array))) // expected-error {{cannot use metatype of type '(Int, Int, Int, Int)' in embedded Swift}}
10+
// expected-note@-1 {{called from here}}
11+
12+
return withUnsafeMutableBytes(of: &array) { ptr in
13+
let buffer = ptr.bindMemory(to: R.self)
14+
precondition(n >= 0)
15+
precondition(n < buffer.count)
16+
buffer[n] = value
17+
}
18+
}
19+
20+
public func test() {
21+
var args: (Int, Int, Int, Int) = (0, 0, 0, 0)
22+
let n = 2
23+
let value = 42
24+
unsafeWriteArray(type(of: args.0), array: &args, index: n, value: value)
25+
}

0 commit comments

Comments
 (0)