llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.69k stars 11.87k forks source link

Internal compiler error on array subscription #76634

Open kelbon opened 10 months ago

kelbon commented 10 months ago
int main() {
    int n;
    int m;
    auto& x = *(int(*)[n][m])(nullptr); // problem is here - binding to reference
    return x[0][0];                               // here internal error
}

That's not best code ever, but i think it need to be fixed()

https://godbolt.org/z/KPoeMGPPd

llvmbot commented 10 months ago

@llvm/issue-subscribers-clang-codegen

Author: None (kelbon)

```cpp int main() { int n; int m; auto& x = *(int(*)[n][m])(nullptr); // problem is here - binding to reference return x[0][0]; // here internal error } ``` That's not best code ever, but i think it need to be fixed() https://godbolt.org/z/KPoeMGPPd
ChipsSpectre commented 9 months ago

Interesting issue, definitely worth fixing. @EugeneZelenko Could you assign me?

The crash is gone when x is only dereferenced once instead of twice: https://godbolt.org/z/ccqn13rss

ChipsSpectre commented 9 months ago

The error can be reproduced in the latest version of clang, and investigating this issue has discovered another source of compiler crashes.

By running the code in a debug build with assertions, it becomes visible that the following assertion (1) breaks:

clang-18: /home/drives/fastSSD/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:2200: clang::CodeGen::CodeGenFunction::VlaSizePair clang::CodeGen::CodeGenFunction::getVLASize(const clang::VariableArrayType*): Assertion `vlaSize && "no size for VLA!"' failed.

That is, the VLA size of a given type could not be found during code generation.

Reducing the code to

int main() {
    int m;
    auto& x = *(int(*)[m])(nullptr);
    return x[0];
}

triggers the following assertion (2):

clang-18: /home/drives/fastSSD/llvm-project/clang/include/clang/AST/Type.h:753: const clang::ExtQualsTypeCommonBase* clang::QualType::getCommonPtr() const: Assertion `!isNull() && "Cannot retrieve a NULL type pointer"' failed.

Interestingly, assertion (2) is triggered if and only if m is not known at compile time. This code generates assertion (2) as well:

int main() {
    int m = 1;
    auto& x = *(int(*)[m])(nullptr);
    return x[0];
}

while the following code compiles:

int main() {
    constexpr int m = 1;
    auto& x = *(int(*)[m])(nullptr);
    return x[0];
}