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

Reply via email to