| Issue |
172165
|
| Summary |
Bytecode interpreter: comparing pointers behave differently than ExprConstant
|
| Labels |
clang:bytecode
|
| Assignees |
|
| Reporter |
hanickadot
|
(I'm not really experienced with the bytecode interpreter, but this seems to me as a bug)
https://compiler-explorer.com/z/vWsW99vW9
Following code works in the AST interpreter in Clang, GCC, EDG, all three static asserts fails in the ByteCode interpreter. (MSVC fails on last two)
```c++
struct tuple {
int a;
int b;
};
constexpr tuple tpl{1,2};
// start of the object VS first member
static_assert(static_cast<const void *>(&tpl) == static_cast<const void *>(&tpl.a)); // bytecode fail
// past the first member VS second member
static_assert(static_cast<const void *>(&tpl.a+1) == static_cast<const void *>(&tpl.b)); // bytecode and MSVC fail
// past the second member VS past the object
static_assert(static_cast<const void *>(&tpl.b+1) == static_cast<const void *>(&tpl+1)); // bytecode and MSVC fail
```
If I do similar code but in runtime:
https://compiler-explorer.com/z/9KdbceaGq (with constexpr compare function)
```c++
#include <cassert>
struct tuple {
int a;
int b;
};
constexpr bool compare(const void * a, const void * b) {
return a == b;
}
int main() {
tuple tpl{1,2};
// start of the object VS first member
assert(compare(&tpl, &tpl.a));
// past the first member VS second member
assert(compare(&tpl.a+1, &tpl.b));
// past the second member VS past the object
assert(compare(&tpl.b+1, &tpl+1));
}
```
Now the runtime code with byte code interpreter crashes on assert's check which is pre-calculated with the bytecode interpreter.
Removing constexpr on `compare`, will make it work in runtime:
https://compiler-explorer.com/z/z91nYhe9Y
```c++
#include <cassert>
struct tuple {
int a;
int b;
};
bool compare(const void * a, const void * b) { // no constexpr here
return a == b;
}
int main() {
tuple tpl{1,2};
// start of the object VS first member
assert(compare(&tpl, &tpl.a));
// past the first member VS second member
assert(compare(&tpl.a+1, &tpl.b));
// past the second member VS past the object
assert(compare(&tpl.b+1, &tpl+1));
}
```
It seems problem is in `clang/lib/AST/ByteCode/Interp.h` https://github.com/llvm/llvm-project/blob/f721a3965caec0a57f1ad3e6e7b2628d2c8a5fa8/clang/lib/AST/ByteCode/Interp.h#L1097-L1101 Where comparison is done thru offsets, but for some reason the first member has offset 16 and not 0.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs