Skip to content

Commit 309c666

Browse files
authored
Merge pull request #19416 from jckarter/better-missing-metadata-warnings-4.2
[4.2] Make runtime warnings about missing metadata more descriptive.
2 parents 55f273a + c3bbc62 commit 309c666

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

include/swift/Runtime/Debug.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ LLVM_ATTRIBUTE_NORETURN
9595
extern void
9696
fatalError(uint32_t flags, const char *format, ...);
9797

98+
/// swift::warning() emits a warning from the runtime.
99+
extern void
100+
warningv(uint32_t flags, const char *format, va_list args);
101+
98102
/// swift::warning() emits a warning from the runtime.
99103
extern void
100104
warning(uint32_t flags, const char *format, ...);

stdlib/public/runtime/Errors.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,22 +349,29 @@ swift::fatalError(uint32_t flags, const char *format, ...)
349349

350350
// Report a warning to system console and stderr.
351351
void
352-
swift::warning(uint32_t flags, const char *format, ...)
352+
swift::warningv(uint32_t flags, const char *format, va_list args)
353353
{
354-
va_list args;
355-
va_start(args, format);
356-
357354
char *log;
358355
#pragma GCC diagnostic push
359356
#pragma GCC diagnostic ignored "-Wuninitialized"
360357
swift_vasprintf(&log, format, args);
361358
#pragma GCC diagnostic pop
362-
359+
363360
reportNow(flags, log);
364-
361+
365362
free(log);
366363
}
367364

365+
// Report a warning to system console and stderr.
366+
void
367+
swift::warning(uint32_t flags, const char *format, ...)
368+
{
369+
va_list args;
370+
va_start(args, format);
371+
372+
warningv(flags, format, args);
373+
}
374+
368375
// Crash when a deleted method is called by accident.
369376
SWIFT_RUNTIME_EXPORT
370377
LLVM_ATTRIBUTE_NORETURN

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,47 @@ swift_getTypeByMangledNameImpl(const char *typeNameStart, size_t typeNameLength,
11151115
});
11161116
}
11171117

1118+
struct swift_closure {
1119+
void *fptr;
1120+
HeapObject *context;
1121+
};
1122+
SWIFT_RUNTIME_STDLIB_API SWIFT_CC(swift) swift_closure
1123+
MANGLE_SYM(s20_playgroundPrintHookySScSgvg)();
1124+
1125+
static bool _shouldReportMissingReflectionMetadataWarnings() {
1126+
// Missing metadata warnings noise up playground sessions and aren't really
1127+
// actionable in playground contexts. If we're running in a playground,
1128+
// suppress warnings.
1129+
//
1130+
// Guesstimate whether we're in a playground by looking at the
1131+
// _playgroundPrintHook variable in the standard library, which is set during
1132+
// playground execution.
1133+
auto hook = MANGLE_SYM(s20_playgroundPrintHookySScSgvg)();
1134+
if (hook.fptr) {
1135+
swift_release(hook.context);
1136+
return false;
1137+
} else {
1138+
return true;
1139+
}
1140+
}
1141+
1142+
/// Raise a warning about reflection metadata that could not be found
1143+
/// at runtime. This is usually mostly harmless, but it's good to alert
1144+
/// users that it happens.
1145+
static void
1146+
missing_reflection_metadata_warning(const char *fmt, ...) {
1147+
bool shouldWarn =
1148+
SWIFT_LAZY_CONSTANT(_shouldReportMissingReflectionMetadataWarnings());
1149+
1150+
if (!shouldWarn)
1151+
return;
1152+
1153+
va_list args;
1154+
va_start(args, fmt);
1155+
1156+
warningv(0, fmt, args);
1157+
}
1158+
11181159
void swift::swift_getFieldAt(
11191160
const Metadata *base, unsigned index,
11201161
void (*callback)(const char *name, const Metadata *type, void *ctx), void *callbackCtx) {
@@ -1182,10 +1223,12 @@ void swift::_swift_getFieldAt(
11821223
// a log message.
11831224
if (typeInfo == nullptr) {
11841225
typeInfo = TypeInfo(&METADATA_SYM(EMPTY_TUPLE_MANGLING), {});
1185-
warning(0, "SWIFT RUNTIME BUG: unable to demangle type of field '%*s'. "
1186-
"mangled type name is '%*s'\n",
1187-
(int)name.size(), name.data(),
1188-
(int)typeName.size(), typeName.data());
1226+
missing_reflection_metadata_warning(
1227+
"warning: the Swift runtime was unable to demangle the type "
1228+
"of field '%*s'. the mangled type name is '%*s'. this field will "
1229+
"show up as an empty tuple in Mirrors\n",
1230+
(int)name.size(), name.data(),
1231+
(int)typeName.size(), typeName.data());
11891232
}
11901233

11911234
callback(name, FieldType()
@@ -1235,8 +1278,11 @@ void swift::_swift_getFieldAt(
12351278
// If we failed to find the field descriptor metadata for the type, fall
12361279
// back to returning an empty tuple as a standin.
12371280
auto typeName = swift_getTypeName(base, /*qualified*/ true);
1238-
warning(0, "SWIFT RUNTIME BUG: unable to find field metadata for type '%*s'\n",
1239-
(int)typeName.length, typeName.data);
1281+
missing_reflection_metadata_warning(
1282+
"warning: the Swift runtime found no field metadata for "
1283+
"type '%*s' that claims to be reflectable. Its fields will show up as "
1284+
"'unknown' in Mirrors\n",
1285+
(int)typeName.length, typeName.data);
12401286
callback("unknown",
12411287
FieldType()
12421288
.withType(TypeInfo(&METADATA_SYM(EMPTY_TUPLE_MANGLING), {}))

unittests/runtime/Stdlib.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,15 @@ const long long $Ss12_ClassMirrorVs01_B0sWP[1] = {0};
252252
// type metadata accessor for Swift._ClassMirror
253253
SWIFT_RUNTIME_STDLIB_INTERNAL
254254
const long long $Ss12_ClassMirrorVMa[1] = {0};
255+
256+
// playground print hook
257+
258+
struct swift_closure {
259+
void *fptr;
260+
HeapObject *context;
261+
};
262+
SWIFT_RUNTIME_STDLIB_API SWIFT_CC(swift) swift_closure
263+
MANGLE_SYM(s20_playgroundPrintHookySScSgvg)() {
264+
return {nullptr, nullptr};
265+
}
266+

0 commit comments

Comments
 (0)