https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/180293

>From f80187c545b8a9775e0b2356fdc04ae3ae35fd2c Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <[email protected]>
Date: Fri, 6 Feb 2026 21:25:55 +0200
Subject: [PATCH 1/3] [Clang] fix crash when constexpr evaluation encounters
 uninitialized GCC vector

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/AST/ExprConstant.cpp                | 20 ++++++++++++++++++-
 .../constexpr-vectors-access-elements.cpp     | 16 +++++++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 24d4e07ca68b3..c9c50625a8590 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -243,6 +243,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 ff433ed729a28..e5732df75ec1e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3599,6 +3599,11 @@ static void expandArray(APValue &Array, unsigned Index) {
   Array.swap(NewValue);
 }
 
+static void expandVector(APValue &Vec, unsigned NumElements) {
+  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,7 +4296,20 @@ findSubobject(EvalInfo &Info, const Expr *E, const 
CompleteObject &Obj,
 
       ObjType = VT->getElementType();
       assert(I == N - 1 && "extracting subobject of scalar?");
-      return handler.found(O->getVectorElt(Index), ObjType);
+
+      if (O->isIndeterminate() || O->isAbsent()) {
+        if (isRead(handler.AccessKind)) {
+          Info.FFDiag(E);
+          return handler.failed();
+        }
+        expandVector(*O, NumElements);
+      }
+
+      if (O->isVector())
+        return handler.found(O->getVectorElt(Index), ObjType);
+
+      Info.FFDiag(E);
+      return handler.failed();
     } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
       if (Field->isMutable() &&
           !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
diff --git a/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp 
b/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
index 58efcde414af2..a84bb319dc0dd 100644
--- a/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
+++ b/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
@@ -46,3 +46,19 @@ 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 test(char c) {
+  T v;
+  for (int i = 0; i < sizeof(T); ++i)
+    v[i] = c;
+  return v;
+}
+
+using T = char __attribute__((vector_size(16)));
+T t1 = test<T>(~1);
+
+constexpr T t2 = test<T>(~1);
+static_assert(t2[0] == -2);
+static_assert(t2[15] == -2);
+}

>From 56ddba28009be3eaa259383e9c7181f100ee3ea6 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <[email protected]>
Date: Mon, 9 Feb 2026 15:20:56 +0200
Subject: [PATCH 2/3] add test to cover read access case

---
 .../constexpr-vectors-access-elements.cpp     | 27 +++++++++++++++----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp 
b/clang/test/SemaCXX/constexpr-vectors-access-elements.cpp
index a84bb319dc0dd..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 {
 
@@ -48,17 +49,33 @@ static_assert(p->x == 1);
 }
 
 namespace GH180044 {
-template <typename T> constexpr T test(char c) {
+template <typename T> constexpr T test1(char c) {
   T v;
   for (int i = 0; i < sizeof(T); ++i)
     v[i] = c;
   return v;
 }
 
-using T = char __attribute__((vector_size(16)));
-T t1 = test<T>(~1);
+using C = char __attribute__((vector_size(16)));
+C t1 = test1<C>(~1);
 
-constexpr T t2 = test<T>(~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@+1 {{constexpr function never produces a constant 
expression}}
+constexpr unsigned test2() {
+  // cpp17-warning@+1 {{uninitialized variable in a constexpr function is a 
C++20 extension}}
+  I v;
+
+  // expected-note@+2 {{subexpression not valid in a constant expression}}
+  // expected-note@+1 {{subexpression not valid in a constant expression}}
+  return __builtin_bit_cast(unsigned, v[0]);
+}
+
+// expected-error@+2 {{static assertion expression is not an integral constant 
expression}}
+// expected-note@+1 {{in call to 'test2()'}}
+static_assert(test2(), "");
 }

>From 40b3ab03f05ec1ee43bb1b08f4a6f7ecf49f9fbc Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <[email protected]>
Date: Mon, 9 Feb 2026 15:21:40 +0200
Subject: [PATCH 3/3] add asserts

---
 clang/lib/AST/ExprConstant.cpp | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e5732df75ec1e..e24fdca90441e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3599,7 +3599,9 @@ 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());
 }
@@ -4297,19 +4299,15 @@ findSubobject(EvalInfo &Info, const Expr *E, const 
CompleteObject &Obj,
       ObjType = VT->getElementType();
       assert(I == N - 1 && "extracting subobject of scalar?");
 
-      if (O->isIndeterminate() || O->isAbsent()) {
+      if (O->isIndeterminate()) {
         if (isRead(handler.AccessKind)) {
           Info.FFDiag(E);
           return handler.failed();
         }
         expandVector(*O, NumElements);
       }
-
-      if (O->isVector())
-        return handler.found(O->getVectorElt(Index), ObjType);
-
-      Info.FFDiag(E);
-      return handler.failed();
+      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() &&
           !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to