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@+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(), "");
+}


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

Reply via email to