[clang] ca8a6b8 - [Clang] fix crash when constexpr evaluation encounters uninitialized GCC vector (#180293)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 13 07:38:10 PST 2026
Author: Oleksandr Tarasiuk
Date: 2026-02-13T17:38:05+02:00
New Revision: ca8a6b8cb14e7006b041da889ba16110ec2cd673
URL: https://github.com/llvm/llvm-project/commit/ca8a6b8cb14e7006b041da889ba16110ec2cd673
DIFF: https://github.com/llvm/llvm-project/commit/ca8a6b8cb14e7006b041da889ba16110ec2cd673.diff
LOG: [Clang] fix crash when constexpr evaluation encounters uninitialized GCC vector (#180293)
Fixes #180044
---
This patch addresses the regression caused by
https://github.com/llvm/llvm-project/commit/77534291fcbd2c784c54e39a60895e4f60f19742.
The crash happens because
https://github.com/llvm/llvm-project/blob/85d94e17144f2ca250c91b827b59e6ddea675d31/clang/lib/AST/ExprConstant.cpp#L4294
tries to read a vector element when the `APValue` is still
`Indeterminate` or `Absent`. These changes _populate_ vector `APValue`
to ensure elements exist before access.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4f732ba81d78f..92731326ca1bf 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -278,6 +278,7 @@ Bug Fixes to C++ Support
- Fixed a crash when instantiating ``requires`` expressions involving substitution failures in C++ concepts. (#GH176402)
- Fixed a crash when a default argument is passed to an explicit object parameter. (#GH176639)
- Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741)
+- Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type vectors in ``constexpr``. (#GH180044)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 23a40c9bfd118..2c13befec02f2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3599,6 +3599,13 @@ static void expandArray(APValue &Array, unsigned Index) {
Array.swap(NewValue);
}
+// Expand an indeterminate vector to materialize all elements.
+static void expandVector(APValue &Vec, unsigned NumElements) {
+ assert(Vec.isIndeterminate());
+ SmallVector<APValue, 4> Elts(NumElements, APValue::IndeterminateValue());
+ Vec = APValue(Elts.data(), Elts.size());
+}
+
/// Determine whether a type would actually be read by an lvalue-to-rvalue
/// conversion. If it's of class type, we may assume that the copy operation
/// is trivial. Note that this is never true for a union type with fields
@@ -4291,6 +4298,15 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
ObjType = VT->getElementType();
assert(I == N - 1 && "extracting subobject of scalar?");
+
+ if (O->isIndeterminate()) {
+ if (isRead(handler.AccessKind)) {
+ Info.FFDiag(E);
+ return handler.failed();
+ }
+ expandVector(*O, NumElements);
+ }
+ assert(O->isVector() && "unexpected object during vector element access");
return handler.found(O->getVectorElt(Index), ObjType);
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
if (Field->isMutable() &&
diff --git a/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp b/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
index 58efcde414af2..481b80ceb9c1e 100644
--- a/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
+++ b/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++17 -fsyntax-only -verify
+// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++17 -fsyntax-only -verify=expected,cpp17
+// RUN: %clang_cc1 %s -Wno-uninitialized -std=c++20 -fsyntax-only -verify=expected,cpp20
namespace Vector {
@@ -46,3 +47,35 @@ static_assert(&b[1]); // expected-error {{address of vector element requested}}
constexpr const FourIntsExtVec *p = &b;
static_assert(p->x == 1);
}
+
+namespace GH180044 {
+template <typename T> constexpr T test1(char c) {
+ T v;
+ for (int i = 0; i < sizeof(T); ++i)
+ v[i] = c;
+ return v;
+}
+
+using C = char __attribute__((vector_size(16)));
+C t1 = test1<C>(~1);
+
+constexpr C t2 = test1<C>(~1);
+static_assert(t2[0] == -2);
+static_assert(t2[15] == -2);
+
+using I = int __attribute__((vector_size(16)));
+
+// expected-error at +1 {{constexpr function never produces a constant expression}}
+constexpr unsigned test2() {
+ // cpp17-warning at +1 {{uninitialized variable in a constexpr function is a C++20 extension}}
+ I v;
+
+ // expected-note at +2 {{subexpression not valid in a constant expression}}
+ // expected-note at +1 {{subexpression not valid in a constant expression}}
+ return __builtin_bit_cast(unsigned, v[0]);
+}
+
+// expected-error at +2 {{static assertion expression is not an integral constant expression}}
+// expected-note at +1 {{in call to 'test2()'}}
+static_assert(test2(), "");
+}
More information about the cfe-commits
mailing list