Skip to content

Commit f965495

Browse files
committed
Swift: replace assertions and direct prints in SwiftDispatcher
Also added opt-in logging of undefined trap labels for all emissions outside the `SwiftDispatcher`.
1 parent 89496a8 commit f965495

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "swift/extractor/infra/SwiftLocationExtractor.h"
1414
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
1515
#include "swift/extractor/config/SwiftExtractorState.h"
16-
#include "swift/extractor/infra/log/SwiftLogging.h"
16+
#include "swift/extractor/infra/log/SwiftAssert.h"
1717

1818
namespace codeql {
1919

@@ -67,21 +67,20 @@ class SwiftDispatcher {
6767
entry.forEachLabel([&valid, &entry, this](const char* field, int index, auto& label) {
6868
using Label = std::remove_reference_t<decltype(label)>;
6969
if (!label.valid()) {
70-
std::cerr << entry.NAME << " has undefined " << field;
71-
if (index >= 0) {
72-
std::cerr << '[' << index << ']';
73-
}
70+
const char* action;
7471
if constexpr (std::is_base_of_v<typename Label::Tag, UnspecifiedElementTag>) {
75-
std::cerr << ", replacing with unspecified element\n";
72+
action = "replacing with unspecified element";
7673
label = emitUnspecified(idOf(entry), field, index);
7774
} else {
78-
std::cerr << ", skipping emission\n";
75+
action = "skipping emission";
7976
valid = false;
8077
}
78+
LOG_ERROR("{} has undefined field {}{}, {}", entry.NAME, field,
79+
index >= 0 ? ('[' + std::to_string(index) + ']') : "", action);
8180
}
8281
});
8382
if (valid) {
84-
trap.emit(entry);
83+
trap.emit(entry, /* check */ false);
8584
}
8685
}
8786

@@ -146,8 +145,8 @@ class SwiftDispatcher {
146145
// this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might
147146
// end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel`
148147
// only after having called `assignNewLabel` on `e`.
149-
assert(std::holds_alternative<std::monostate>(waitingForNewLabel) &&
150-
"fetchLabel called before assignNewLabel");
148+
CODEQL_ASSERT(std::holds_alternative<std::monostate>(waitingForNewLabel),
149+
"fetchLabel called before assignNewLabel");
151150
if (auto l = store.get(e)) {
152151
return *l;
153152
}
@@ -162,8 +161,8 @@ class SwiftDispatcher {
162161
}
163162
return *l;
164163
}
165-
assert(!"assignNewLabel not called during visit");
166-
return {};
164+
LOG_CRITICAL("assignNewLabel not called during visit");
165+
abort();
167166
}
168167

169168
// convenience `fetchLabel` overload for `swift::Type` (which is just a wrapper for
@@ -184,7 +183,7 @@ class SwiftDispatcher {
184183
// declarations
185184
template <typename E, typename... Args, std::enable_if_t<IsStorable<E>>* = nullptr>
186185
TrapLabel<ConcreteTrapTagOf<E>> assignNewLabel(const E& e, Args&&... args) {
187-
assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity");
186+
CODEQL_ASSERT(waitingForNewLabel == Store::Handle{e}, "assignNewLabel called on wrong entity");
188187
auto label = trap.createLabel<ConcreteTrapTagOf<E>>(std::forward<Args>(args)...);
189188
store.insert(e, label);
190189
waitingForNewLabel = std::monostate{};
@@ -332,7 +331,10 @@ class SwiftDispatcher {
332331
SwiftBodyEmissionStrategy& bodyEmissionStrategy;
333332
Store::Handle waitingForNewLabel{std::monostate{}};
334333
std::unordered_set<swift::ModuleDecl*> encounteredModules;
335-
Logger logger{"dispatcher"};
334+
Logger& logger() {
335+
static Logger ret{"dispatcher"};
336+
return ret;
337+
}
336338
};
337339

338340
} // namespace codeql

swift/extractor/trap/TrapDomain.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,16 @@ class TrapDomain {
2020
}
2121

2222
template <typename Entry>
23-
void emit(const Entry& e) {
23+
void emit(const Entry& e, bool check = true) {
2424
LOG_TRACE("{}", e);
25+
if (check) {
26+
e.forEachLabel([&e, this](const char* field, int index, auto& label) {
27+
if (!label.valid()) {
28+
LOG_ERROR("{} has undefined field {}{}", e.NAME, field,
29+
index >= 0 ? ('[' + std::to_string(index) + ']') : "");
30+
}
31+
});
32+
}
2533
out << e << '\n';
2634
}
2735

@@ -34,7 +42,9 @@ class TrapDomain {
3442

3543
template <typename... Args>
3644
void debug(const Args&... args) {
37-
emitComment("DEBUG:\n", args..., '\n');
45+
out << "/* DEBUG:\n";
46+
(out << ... << args);
47+
out << "\n*/\n";
3848
}
3949

4050
template <typename Tag>

swift/extractor/trap/TrapLabel.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ class UntypedTrapLabel {
3434
explicit operator bool() const { return valid(); }
3535

3636
friend std::ostream& operator<<(std::ostream& out, UntypedTrapLabel l) {
37-
// TODO: this is a temporary fix to catch us from outputting undefined labels to trap
38-
// this should be moved to a validity check, probably aided by code generation and carried out
39-
// by `SwiftDispatcher`
40-
assert(l && "outputting an undefined label!");
4137
out << '#' << std::hex << l.id_ << std::dec;
4238
return out;
4339
}

0 commit comments

Comments
 (0)