-
Notifications
You must be signed in to change notification settings - Fork 336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unaligned memory access in order_by #355
Comments
That is interesting. It is complaining about a static_cast to the derived class in a variadic CRTP. We might need a language lawyer to see if that is valid or not? |
I haven't seen CRTP before and I have hard time following the code. |
This is a drastically simplified version of what is happening: #include <iostream>
#include <string_view>
template<typename Derived>
struct Base1
{
constexpr auto& get1() const
{
return static_cast<const Derived&>(*this);
}
};
template<typename Derived>
struct Base2
{
constexpr auto& get2() const
{
return static_cast<const Derived&>(*this);
}
};
template<typename Derived>
struct Base3
{
constexpr auto& get3() const
{
return static_cast<const Derived&>(*this);
}
};
struct X : public Base1<X>, public Base2<X>, public Base3<X>
{
constexpr X(std::string_view d) : data{d} {}
std::string_view data;
};
int main()
{
constexpr auto x = X{"cheesecake"};
static_assert(x.get1().data == x.get2().data);
static_assert(&x.get1() == &x.get2());
static_assert(&x.get1() == &x.get3());
std::cout << "Base1: " << alignof(Base1<X>) << std::endl; // 1
std::cout << "Base2: " << alignof(Base2<X>) << std::endl; // 1
std::cout << "Base3: " << alignof(Base3<X>) << std::endl; // 1
std::cout << "X : " << alignof(X) << std::endl; // 8
}
This is using C++17, but that's just to make the code slightly more concise. Judging by the static_asserts, this seems to be OK despite the different alignments (I'll need to experiment with UB sanitizer, though). |
I tried to reproduce your code sample: #include <iostream>
#include <sqlpp11/sqlpp11.h>
#include <MockDb.h>
#include <Sample.h>
int main()
{
const auto t = test::TabBar{};
auto db = MockDb{};
for (const auto& row : db(select(all_of(t)).from(t).where(t.alpha > 15).order_by(t.alpha.asc()).limit(100u)))
{
std::cout << row.alpha;
}
} Compiled with clang-12
I got no alignment warnings when running it. I also tried with Can you create a minimal viable example of the problem? |
Here's a sample which produces the issue and then crashes:
The issue occurs when I compile with gcc 9.3.0 but not with clang 11.0. |
BTW, one could add one more assertion that also passes: |
Thanks for the example! I can reproduce it with gcc-11, too. I'll try to create a minimal example that exposes the behavior and then start looking for a language lawyer. |
I found a minimal example and posted the question on stackoverflow. |
The answer on stackoverflow seems very plausible to me. I filed a bug for gcc. |
FYI: The gcc sanitizer bug is now fixed in trunk: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98206 I tested with the example above: Works fine now. |
We're running our unit tests with undefined behaviour sanitizer and it has caught the following misaligned access:
While executing
The text was updated successfully, but these errors were encountered: