[PATCH] D137415: [clang][Interp] Implement switch statements
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 28 14:49:22 PST 2022
aaron.ballman added inline comments.
================
Comment at: clang/lib/AST/Interp/ByteCodeStmtGen.cpp:423
+ // Create labels and comparison ops for all case statements.
+ for (const SwitchCase *SC = S->getSwitchCaseList(); SC;
+ SC = SC->getNextSwitchCase()) {
----------------
How well does this handle large switch statements? Generated code sometimes winds up with thousands of cases, so I'm wondering if we need to have a jump table implementation for numerous cases and use the simple comparison implementation when there's only a small number of labels (and we can test to see what constitutes a good value for "small number of labels").
Also, one thing to be aware of (that hopefully won't matter TOO much in this case): the switch case list does not have a stable iteration order IIRC.
================
Comment at: clang/test/AST/Interp/switch.cpp:16-18
+ case 11:
+ case 13:
+ case 15:
----------------
lol, you should probably fix this so it's not so confusing to casual readers.
================
Comment at: clang/test/AST/Interp/switch.cpp:46
+constexpr int withInit() {
+ switch(int a = 2; a) {
+ case 1: return -1;
----------------
I think it would be good to add a non-trivial init and show that it fails when appropriate. e.g.,
```
struct Weirdo {
consteval Weirdo(int);
Weirdo(double);
int Val = 1;
};
constexpr int whatever() {
switch (Weirdo W(12); W.Val) {
case 1: return 12;
default: return 100;
}
}
constexpr int whatever_else() {
switch (Weirdo W(1.2); W.Val) { // Should get an error because of the init not being constexpr
case 1: return 12;
default: return 100;
}
}
static_assert(whatever() == 12, "");
static_assert(whatever_else() == 12, ""); // Shouldn't compile because the function isn't constexpr
```
================
Comment at: clang/test/AST/Interp/switch.cpp:68
+static_assert(FT(4) == 4, "");
+static_assert(FT(5) == -1, "");
----------------
I'd like a test where the case value is itself a constant expression that is either valid or invalid:
```
constexpr int good() { return 1; }
constexpr int test(int val) {
switch (val) {
case good(): return 100;
default: return -1;
}
return 0;
}
static_assert(test(1) == 100, "");
constexpr int bad(int val) { return val / 0; }
constexpr int another_test(int val) {
switch (val) {
case bad(val): return 100; // Should not compile
default: return -1;
}
return 0;
}
static_assert(another_test(1) == 100, ""); // Should not compile
```
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137415/new/
https://reviews.llvm.org/D137415
More information about the cfe-commits
mailing list