-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Description
(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)
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 failIf I do similar code but in runtime:
https://compiler-explorer.com/z/9KdbceaGq (with constexpr compare function)
#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
#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
llvm-project/clang/lib/AST/ByteCode/Interp.h
Lines 1097 to 1101 in f721a39
| if (Pointer::hasSameBase(LHS, RHS)) { | |
| size_t A = LHS.computeOffsetForComparison(); | |
| size_t B = RHS.computeOffsetForComparison(); | |
| S.Stk.push<BoolT>(BoolT::from(Fn(Compare(A, B)))); | |
| return true; |