Skip to content

Commit 8be084f

Browse files
authored
Merge pull request #39187 from al45tair/problem/79725187
[Demangler] Improve remangler error handling
2 parents e7342eb + af13791 commit 8be084f

File tree

29 files changed

+2995
-1903
lines changed

29 files changed

+2995
-1903
lines changed

include/swift/Demangling/Demangle.h

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
#ifndef SWIFT_DEMANGLING_DEMANGLE_H
2020
#define SWIFT_DEMANGLING_DEMANGLE_H
2121

22-
#include <memory>
23-
#include <string>
22+
#include "swift/Demangling/NamespaceMacros.h"
23+
#include "swift/Runtime/Config.h"
24+
#include "llvm/ADT/StringRef.h"
2425
#include <cassert>
2526
#include <cstdint>
26-
#include "llvm/ADT/StringRef.h"
27-
#include "swift/Demangling/NamespaceMacros.h"
27+
#include <memory>
28+
#include <string>
2829

2930
namespace llvm {
3031
class raw_ostream;
@@ -512,42 +513,113 @@ enum class OperatorKind {
512513
Infix,
513514
};
514515

516+
/// A mangling error, which consists of an error code and a Node pointer
517+
struct SWIFT_NODISCARD ManglingError {
518+
enum Code {
519+
Success = 0,
520+
AssertionFailed,
521+
Uninitialized,
522+
TooComplex,
523+
BadNodeKind,
524+
BadNominalTypeKind,
525+
NotAStorageNode,
526+
UnsupportedNodeKind,
527+
UnexpectedBuiltinVectorType,
528+
UnexpectedBuiltinType,
529+
MultipleChildNodes,
530+
WrongNodeType,
531+
WrongDependentMemberType,
532+
BadDirectness,
533+
UnknownEncoding,
534+
InvalidImplCalleeConvention,
535+
InvalidImplDifferentiability,
536+
InvalidImplFunctionAttribute,
537+
InvalidImplParameterConvention,
538+
InvalidMetatypeRepresentation,
539+
MultiByteRelatedEntity,
540+
BadValueWitnessKind,
541+
NotAContextNode,
542+
};
543+
544+
Code code;
545+
NodePointer node;
546+
unsigned line;
547+
548+
ManglingError() : code(Uninitialized), node(nullptr) {}
549+
ManglingError(Code c) : code(c), node(nullptr), line(0) {}
550+
ManglingError(Code c, NodePointer n, unsigned l) : code(c), node(n), line(l) {}
551+
552+
bool isSuccess() const { return code == Success; }
553+
};
554+
555+
#define MANGLING_ERROR(c,n) ManglingError((c), (n), __LINE__)
556+
557+
/// Used as a return type for mangling functions that may fail
558+
template <typename T>
559+
class SWIFT_NODISCARD ManglingErrorOr {
560+
private:
561+
ManglingError err_;
562+
T value_;
563+
564+
public:
565+
ManglingErrorOr() : err_() {}
566+
ManglingErrorOr(ManglingError::Code code,
567+
NodePointer node = nullptr,
568+
unsigned line = 0)
569+
: err_(code, node, line) {}
570+
ManglingErrorOr(const ManglingError &err) : err_(err) {}
571+
ManglingErrorOr(const T &t) : err_(ManglingError::Success), value_(t) {}
572+
ManglingErrorOr(T &&t) : err_(ManglingError::Success), value_(std::move(t)) {}
573+
574+
bool isSuccess() const { return err_.code == ManglingError::Success; }
575+
576+
const ManglingError &error() const { return err_; }
577+
578+
const T &result() const {
579+
assert(isSuccess());
580+
return value_;
581+
}
582+
};
583+
515584
/// Remangle a demangled parse tree.
516-
std::string mangleNode(NodePointer root);
585+
ManglingErrorOr<std::string> mangleNode(NodePointer root);
517586

518587
using SymbolicResolver =
519588
llvm::function_ref<Demangle::NodePointer (SymbolicReferenceKind,
520589
const void *)>;
521590

522591
/// Remangle a demangled parse tree, using a callback to resolve
523592
/// symbolic references.
524-
std::string mangleNode(NodePointer root, SymbolicResolver resolver);
593+
ManglingErrorOr<std::string> mangleNode(NodePointer root, SymbolicResolver resolver);
525594

526595
/// Remangle a demangled parse tree, using a callback to resolve
527596
/// symbolic references.
528597
///
529598
/// The returned string is owned by \p Factory. This means \p Factory must stay
530599
/// alive as long as the returned string is used.
531-
llvm::StringRef mangleNode(NodePointer root, SymbolicResolver resolver,
532-
NodeFactory &Factory);
600+
ManglingErrorOr<llvm::StringRef> mangleNode(NodePointer root,
601+
SymbolicResolver resolver,
602+
NodeFactory &Factory);
533603

534604
/// Remangle in the old mangling scheme.
535605
///
536606
/// This is only used for objc-runtime names.
537-
std::string mangleNodeOld(NodePointer root);
607+
ManglingErrorOr<std::string> mangleNodeOld(NodePointer root);
538608

539609
/// Remangle in the old mangling scheme.
540610
///
541611
/// This is only used for objc-runtime names.
542612
/// The returned string is owned by \p Factory. This means \p Factory must stay
543613
/// alive as long as the returned string is used.
544-
llvm::StringRef mangleNodeOld(NodePointer node, NodeFactory &Factory);
614+
ManglingErrorOr<llvm::StringRef> mangleNodeOld(NodePointer node,
615+
NodeFactory &Factory);
545616

546617
/// Remangle in the old mangling scheme and embed the name in "_Tt<name>_".
547618
///
548619
/// The returned string is null terminated and owned by \p Factory. This means
549620
/// \p Factory must stay alive as long as the returned string is used.
550-
const char *mangleNodeAsObjcCString(NodePointer node, NodeFactory &Factory);
621+
ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node,
622+
NodeFactory &Factory);
551623

552624
/// Transform the node structure to a string.
553625
///
@@ -626,7 +698,7 @@ bool nodeConsumesGenericArgs(Node *node);
626698

627699
bool isSpecialized(Node *node);
628700

629-
NodePointer getUnspecialized(Node *node, NodeFactory &Factory);
701+
ManglingErrorOr<NodePointer> getUnspecialized(Node *node, NodeFactory &Factory);
630702

631703
/// Returns true if the node \p kind refers to a context node, e.g. a nominal
632704
/// type or a function.

include/swift/Demangling/TypeDecoder.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,14 @@ class TypeDecoder {
608608
return decodeMangledType(genericArgs->getChild(0), depth + 1);
609609
}
610610
case NodeKind::BuiltinTypeName: {
611-
auto mangledName = Demangle::mangleNode(Node);
612-
return Builder.createBuiltinType(Node->getText().str(), mangledName);
611+
auto mangling = Demangle::mangleNode(Node);
612+
if (!mangling.isSuccess()) {
613+
return MAKE_NODE_TYPE_ERROR(Node,
614+
"failed to mangle node (%d:%u)",
615+
mangling.error().code,
616+
mangling.error().line);
617+
}
618+
return Builder.createBuiltinType(Node->getText().str(), mangling.result());
613619
}
614620
case NodeKind::Metatype:
615621
case NodeKind::ExistentialMetatype: {
@@ -1373,7 +1379,11 @@ return {}; // Not Implemented!
13731379
parent = decodeMangledType(parentContext, depth + 1).getType();
13741380
// Remove any generic arguments from the context node, producing a
13751381
// node that references the nominal type declaration.
1376-
declNode = Demangle::getUnspecialized(node, Builder.getNodeFactory());
1382+
auto unspec =
1383+
Demangle::getUnspecialized(node, Builder.getNodeFactory());
1384+
if (!unspec.isSuccess())
1385+
return TypeLookupError("Failed to unspecialize type");
1386+
declNode = unspec.result();
13771387
break;
13781388
}
13791389
}

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ class TypeRefBuilder {
289289
void clearNodeFactory() { Dem.clear(); }
290290

291291
BuiltType decodeMangledType(Node *node);
292-
292+
293293
///
294294
/// Factory methods for all TypeRef kinds
295295
///
@@ -300,12 +300,20 @@ class TypeRefBuilder {
300300
}
301301

302302
llvm::Optional<std::string> createTypeDecl(Node *node, bool &typeAlias) {
303-
return Demangle::mangleNode(node);
303+
auto mangling = Demangle::mangleNode(node);
304+
if (!mangling.isSuccess()) {
305+
return llvm::None;
306+
}
307+
return mangling.result();
304308
}
305309

306310
BuiltProtocolDecl
307311
createProtocolDecl(Node *node) {
308-
return std::make_pair(Demangle::mangleNode(node), false);
312+
auto mangling = Demangle::mangleNode(node);
313+
if (!mangling.isSuccess()) {
314+
return llvm::None;
315+
}
316+
return std::make_pair(mangling.result(), false);
309317
}
310318

311319
BuiltProtocolDecl
@@ -395,12 +403,16 @@ class TypeRefBuilder {
395403

396404
return underlyingTy->subst(*this, subs);
397405
}
398-
406+
407+
auto mangling = mangleNode(opaqueDescriptor,
408+
SymbolicResolver(),
409+
Dem);
410+
if (!mangling.isSuccess())
411+
return nullptr;
412+
399413
// Otherwise, build a type ref that represents the opaque type.
400414
return OpaqueArchetypeTypeRef::create(*this,
401-
mangleNode(opaqueDescriptor,
402-
SymbolicResolver(),
403-
Dem),
415+
mangling.result(),
404416
nodeToString(opaqueDescriptor),
405417
ordinal,
406418
genericArgs);

include/swift/Remote/MetadataReader.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,11 @@ class MetadataReader {
933933
if (!node || node->getKind() != Node::Kind::Type)
934934
return BuiltType();
935935

936-
auto name = Demangle::mangleNode(node);
936+
auto mangling = Demangle::mangleNode(node);
937+
if (!mangling.isSuccess())
938+
return BuiltType();
939+
auto name = mangling.result();
940+
937941
auto BuiltForeign = Builder.createForeignClassType(std::move(name));
938942
TypeCache[MetadataAddress] = BuiltForeign;
939943
return BuiltForeign;

lib/AST/ASTDemangler.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,11 @@ Type ASTBuilder::resolveOpaqueType(NodePointer opaqueDescriptor,
250250
auto definingDecl = opaqueDescriptor->getChild(0);
251251
auto definingGlobal = Factory.createNode(Node::Kind::Global);
252252
definingGlobal->addChild(definingDecl, Factory);
253-
auto mangledName = mangleNode(definingGlobal);
254-
253+
auto mangling = mangleNode(definingGlobal);
254+
if (!mangling.isSuccess())
255+
return Type();
256+
auto mangledName = mangling.result();
257+
255258
auto moduleNode = findModuleNode(definingDecl);
256259
if (!moduleNode)
257260
return Type();
@@ -935,7 +938,10 @@ ASTBuilder::findDeclContext(NodePointer node) {
935938
if (!module) return nullptr;
936939

937940
// Look up the local type by its mangling.
938-
auto mangledName = Demangle::mangleNode(node);
941+
auto mangling = Demangle::mangleNode(node);
942+
if (!mangling.isSuccess()) return nullptr;
943+
auto mangledName = mangling.result();
944+
939945
auto decl = module->lookupLocalType(mangledName);
940946
if (!decl) return nullptr;
941947

lib/AST/ASTMangler.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,11 @@ std::string ASTMangler::mangleSILDifferentiabilityWitness(StringRef originalName
547547
Demangler demangler;
548548
auto *node = mangleSILDifferentiabilityWitnessAsNode(
549549
originalName, kind, config, demangler);
550-
return mangleNode(node);
550+
auto mangling = mangleNode(node);
551+
if (!mangling.isSuccess()) {
552+
llvm_unreachable("unexpected mangling failure");
553+
}
554+
return mangling.result();
551555
}
552556
beginManglingWithoutPrefix();
553557
appendOperator(originalName);
@@ -721,8 +725,11 @@ std::string ASTMangler::mangleObjCRuntimeName(const NominalTypeDecl *Nominal) {
721725
TyMangling->addChild(Ty, Dem);
722726
Node *NewGlobal = Dem.createNode(Node::Kind::Global);
723727
NewGlobal->addChild(TyMangling, Dem);
724-
std::string OldName = mangleNodeOld(NewGlobal);
725-
return OldName;
728+
auto mangling = mangleNodeOld(NewGlobal);
729+
if (!mangling.isSuccess()) {
730+
llvm_unreachable("unexpected mangling failure");
731+
}
732+
return mangling.result();
726733
#endif
727734
}
728735

lib/Basic/Mangler.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,12 @@ void Mangler::verify(StringRef nameStr) {
176176
llvm::errs() << "Can't demangle: " << nameStr << '\n';
177177
abort();
178178
}
179-
std::string Remangled = mangleNode(Root);
179+
auto mangling = mangleNode(Root);
180+
if (!mangling.isSuccess()) {
181+
llvm::errs() << "Can't remangle: " << nameStr << '\n';
182+
abort();
183+
}
184+
std::string Remangled = mangling.result();
180185
if (Remangled == nameStr)
181186
return;
182187

lib/Demangling/Context.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ std::string Context::getModuleName(llvm::StringRef mangledName) {
217217
}
218218
default:
219219
if (isSpecialized(node)) {
220-
node = getUnspecialized(node, *D);
220+
auto unspec = getUnspecialized(node, *D);
221+
if (!unspec.isSuccess())
222+
node = nullptr;
223+
else
224+
node = unspec.result();
221225
break;
222226
}
223227
if (isContext(node->getKind())) {

lib/Demangling/Demangler.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "swift/Demangling/Demangler.h"
18-
#include "swift/Demangling/ManglingUtils.h"
18+
#include "DemanglerAssert.h"
1919
#include "swift/Demangling/ManglingMacros.h"
20+
#include "swift/Demangling/ManglingUtils.h"
2021
#include "swift/Demangling/Punycode.h"
2122
#include "swift/Strings.h"
23+
#include <stdio.h>
24+
#include <stdlib.h>
2225

2326
using namespace swift;
2427
using namespace Mangle;
@@ -87,6 +90,14 @@ static bool isRequirement(Node::Kind kind) {
8790
// Public utility functions //
8891
//////////////////////////////////
8992

93+
SWIFT_NORETURN void swift::Demangle::failAssert(const char *file, unsigned line,
94+
NodePointer node,
95+
const char *expr) {
96+
fprintf(stderr, "%s:%u: assertion failed for Node %p: %s", file, line, node,
97+
expr);
98+
abort();
99+
}
100+
90101
bool swift::Demangle::isContext(Node::Kind kind) {
91102
switch (kind) {
92103
#define NODE(ID)

0 commit comments

Comments
 (0)