https://github.com/Serosh-commits updated 
https://github.com/llvm/llvm-project/pull/180261

>From f7c46f248546424d9e66617969b4d4ad7c6d66c8 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Fri, 13 Feb 2026 21:51:25 +0530
Subject: [PATCH] Fix crash when constexpr variables have invalid initializers

---
 a.out                                         | Bin 0 -> 16032 bytes
 apply_comprehensive_fix.py                    |  66 +++++++++++
 clang/lib/AST/ByteCode/Pointer.cpp            | 111 +++++++++++-------
 clang/lib/AST/ByteCode/Pointer.h              |  26 +++-
 clang/lib/Sema/SemaDecl.cpp                   |   9 +-
 .../SemaCXX/constexpr-invalid-initializer.cpp |  13 ++
 final_apply.py                                |  66 +++++++++++
 final_apply_perfect.py                        | 105 +++++++++++++++++
 final_logic_fix.py                            |  20 ++++
 repro_180251.c                                |  15 +++
 repro_180251.ll                               | 107 +++++++++++++++++
 repro_180307.cpp                              |   3 +
 repro_bytecode.cpp                            |  13 ++
 repro_const_crash.cpp                         |   2 +
 repro_no_init.cpp                             |   2 +
 repro_non_constexpr.cpp                       |   1 +
 repro_normal.cpp                              |   1 +
 repro_ptrmem_array.cpp                        |   7 ++
 repro_ptrmem_array_records.cpp                |  10 ++
 repro_ptrmem_crash.cpp                        |  11 ++
 repro_ptrmem_multi_array.cpp                  |  11 ++
 repro_scalar.cpp                              |   1 +
 test-invalid-constexpr.cpp                    |   2 +
 test.cpp                                      |   1 +
 test2.cpp                                     |   1 +
 test3.cpp                                     |   1 +
 test_crash.cpp                                |  12 ++
 test_masking.cpp                              |   2 +
 test_no_init.cpp                              |   1 +
 test_output.txt                               |  10 ++
 test_pm.cpp                                   |   2 +
 31 files changed, 582 insertions(+), 50 deletions(-)
 create mode 100755 a.out
 create mode 100644 apply_comprehensive_fix.py
 create mode 100644 clang/test/SemaCXX/constexpr-invalid-initializer.cpp
 create mode 100644 final_apply.py
 create mode 100644 final_apply_perfect.py
 create mode 100644 final_logic_fix.py
 create mode 100644 repro_180251.c
 create mode 100644 repro_180251.ll
 create mode 100644 repro_180307.cpp
 create mode 100644 repro_bytecode.cpp
 create mode 100644 repro_const_crash.cpp
 create mode 100644 repro_no_init.cpp
 create mode 100644 repro_non_constexpr.cpp
 create mode 100644 repro_normal.cpp
 create mode 100644 repro_ptrmem_array.cpp
 create mode 100644 repro_ptrmem_array_records.cpp
 create mode 100644 repro_ptrmem_crash.cpp
 create mode 100644 repro_ptrmem_multi_array.cpp
 create mode 100644 repro_scalar.cpp
 create mode 100644 test-invalid-constexpr.cpp
 create mode 100644 test.cpp
 create mode 100644 test2.cpp
 create mode 100644 test3.cpp
 create mode 100644 test_crash.cpp
 create mode 100644 test_masking.cpp
 create mode 100644 test_no_init.cpp
 create mode 100644 test_output.txt
 create mode 100644 test_pm.cpp

diff --git a/a.out b/a.out
new file mode 100755
index 
0000000000000000000000000000000000000000..8fde856168794c0e1672c521869bf1c18da3885b
GIT binary patch
literal 16032
zcmeHOU2Ggz6~4R4CT^S9PMT0Bq4iMNC_#AR^&e>}lXd))b;yrN94M4_nB5)QtL%@p
zJ0^Ca)Wv{gtfG_vQeVmwBC1prP$eFUs!an)fC^mkK<EnwQOQvXBv6pcPnPe@oU`7&
ztf9R0p_*&$eD{3koO{onxih}AbMF&_M}~rdfReIKeOQq+(&#Z!Ru~`R3LvWXsd^mm
zQ}?P3kk`AMr;mC7tydb?Rbw6VM3djwS+C=J*-lU*BqYDJ$}9zhBB=O#kY9)tEbF)<
zNJ^yyMPKgEaMem_xWu$zr5}Z|*yb55_EzHv_xEW=@gtG^me_BJ{mMuIk)BcVNjag<
z2<KBr13D^(dsIsIn`A#7Ti9NZ`k+EcpQ3>SijIcMuJ$K>Ctr7xRM+DZS@)ATN7%24
z4Rmbb{sg7JkHU|K1Y7)fkl}HH`&;Y$wexus<kR8igxa97cIenC6`WN?iltJ&4Kk&h
z^xw!ldL#a1^UBMu4}Wm(xzjJa^6SoXd()|SPuJdbvMrs;PEEH>@9Syn=?WKe;SRSQ
zYD?Nf^=*}{u%eG%Y!HS{LZ<d>*>|qNKMCHzM=xhV7&-}=&eQ!hcx9Re$4Z<w6BDP+
zF)Nh@fpjE@%{yksN@c+$rY&<Um9^5T$80s3Pi37kMOKuf9(Cx*@WFnwBis@0F4w!t
zwazYO4v!u+lXl)7PZb<HKYFx3oy*#zRy=K^@$pP9%iWotX-z|=g2>W3obdquWV{ix
zAKy#H(bUe=9dxA(Ft;t0+DvDEgyk2W{w9WJP<@hfA@>Ox_t7n$;u_xvgulrhG(|nV
z@FEuvcsz}LI+s$eR`7D`A>CpH@7^cb;aUY>c^xfP@EfIZ!l)+@$F~%hsH@;5SDvMR
z^fTaRz|Vl60Y3wN2K)^88F(i%@Rx@B{vMlqqb{}(y0}-V*q4e<u(TMP`%&E`H;hvE
zPeGSjU%|1VIf@#|6QsMoR6=QenPi$`USEVr?M41DJpbyWvH9P{=6-*3WOOi6jQk|_
zRPS$LQ`-I!n7=s|ZfO1@wV}X2119!V=xYQItT@{dN|@>h<&M%)L-Q=zU1EfN%C+x~
z6YRMio4*;m_{RgWi!1A5fy=R1Z#&!2z`w#?19hdPv4&<$zQv#7o9%6dubS#S6`SjQ
z4VEf4|GKj|w$Qr)d};etP|FE?naiPnq8fPQ(rUbDC#uF)WoqyGIBYq-Q)mkLG?KA}
z^{u<zrUzH948DPyx)S;>b%rw6`yJFaJbrI15qcK2%LAc5Z(InSLv^kgm=Apgl^d^J
z34I<&v+=p!GpMQ0?SXw3wT74A&>0#>bv|U_xDfg{j&sZKJ%-ASpD%PD1|nO{^-4vG
z%cHkTrPY`gj;_QWxH?rADdJ2Uk6c=Ag<6%zLiy}dtbXw`;Ag<kfS&<B1AYel4EP!F
zGvH^y&w!tScS8mOc=wc;uoI^XQyHVzXl>v3(4F+X0=w2d*aD<?ICVEmrH6p~fKkF*
zrP3^r3cbsu5_s%{3QRW!c5T{NcNV_}5Kr&!Z~m!NdOsNqY;@mPQJY=(oCn`de0}3k
zebeEFyUx_jsslS8{6J@m`&!U|>Qne!K%XxHRbPGMmxKMAHw3?j9{M(I;P+qap`t4N
z0736lsSrmWzxWyOGvH^y&w!r+KLdUS{0#UR@H60N;N6@7SuZH-1L?Vl3av?`vdM$;
z0!1uFbjv1Q?74$wS%<ibWm#XilVw?tDC@ID|JU249GP6;#ecGv@GL)&$r{2%*1Hdz
zuz!x*y^FDlaXX^`yQyVfe<*7h-DgP{$@8eJNxX+0N4R6*&vIZAcaiO|Sko=i|36CJ
z_W|je;ytPR{YKayZ+=}_@{Gq-SKiP1w^)|Ax%qb-Wc|3_aSuO74>5{f){!3S@856i
z#*_6PBhrl(wGpGEy`!f+(%z{OX)8N!e8$cfQn{?r5eY}I_I9m8`B|@Sm2^GjJAjqO
zMZ?oDsJkK7vTp_-RGZbT7VrC*zo7B-TLan4^#IW=hj9$39m<G$vYfw<x%@UI<J;3J
z^*Acjj$B{D&%5?_E4f~TKaWbS_<yhlf6;Aci~6B~idJg1^9$Gn)OMwx*K4kCqmuRU
z($o#t{+{x6BRp;WsI|`fKJbPZRp1$yZ&HoX3KG@*;L&S2pQ7ypzcpB|<o+W3A>u`-
z!1x;c6t}PU`vveug}+pv2EQfPq+}cm|19yUq3k5T6Fm>U5#ymfDwZC87W`J6_Yodf
z?r&L8eV^@R{D{{}V$bWg-QTXDyaav=+HZ+^meTJP=67rS&xl9-di%cuZ+J~q9dCiZ
zzl!mMO+m^(?yA~#p-v|9P9&VedUq?HG97DNfrw*8eD);R)y46qlQ9#tJiY+aWX>E<
z=i*k{Ogg!I!L+8PRU(&}Oxuo~47b;|pq2V5)5_<q8Pm=>`585qw=%YwoXTWo;8G!(
zuym?S^Y&yuXGZq5cXUU>35wCqCMiPG96Hf=bkH0;Heh0z{=g@W^&K7V2aS7`IT&MY
zY~X}44;?vvu<wX@d}!$8;HWv;cksv{JoIe^QQ0=|zcvWiNz1X6`>oJQ^=^f7BVD{L
zp-j+b1SAly-rfQT)f)}WWFcoxSlJ|PLKr>{t7Ix`P8IB=LfUXJ<AnnIy4xVe%}zCL
zQmfd&AbFsj4K=qbRBxK74vVs`RJbscajZDd$$K~<wQSC@!{gbhFiys#op)wbxJ<>T
zQrM}IN~$onVc7Xe<r+>{g$Wf-&ScT3hfdzp@IQ<y!Gtbvr!8{e+GN_H77<w3v8QpQ
zQ3PGi&3@RP;BhmNgs(^(R^P$lHX6~czc-vbf2pGzE0anfh8$YPA?$YNHH|c@Fh+F-
zgSEyL_5V>cf1)`DE<?A-J|{tgc>$S^h>S&CRsNGakq~SVLq@r;2;GMYZVl!B*V<<%
z_GDXGh9Ue7a~O&L0{1T{^FNvA>G7Y0Kh5dHf06wKi_lS_=^6Dc{xbi17#z8Xzsw^A
zW!?xAx9IUFz|tH|{AFGyD7Qt4U+e@Y;ZJiuk!9W|7<GI7&-j^EPoP5QMEqsmDOhAf
z>0kf;G`}GKgKQ`BSi$xRf12y+{^!6^PI&se`hS4GxXkal8MiN~6Mhw+N`Hg>1f_rR
zVRiZ6%`=+6{2vv3Q9EJcFYSFx^Ot#qpgg~by*~cG&Hj>qWw0fq{(PbPKd<@Ayh^Zz
zn-kFe>Hj}{Md?3kc$R{*o>)H0`4i&Ds8rrRiiW2VWYHsW)cgM>III9I@5PdNs_bjj
z`x9C4H}J)5sq8QF;%jXnQN+%ZR%PL7-brJRFZ=R*wY<MI;CagU6h9dUZ$eEb;xGH!
zihDi3-5!*W;xG6XG?o7H+_?NU{ey6>^q2W(BM*FuQv#5F%QBpallYCOr!m&>*U#T(
z?w`%2Stb5DPq9*|L>YUY#ygI%<9QB@?&CBcm-yxWOV4K#yXWa0S2{i1sx>bCiY-lp
QYx&>FkBaZn95hk=8{)tb?EnA(

literal 0
HcmV?d00001

diff --git a/apply_comprehensive_fix.py b/apply_comprehensive_fix.py
new file mode 100644
index 0000000000000..3dbdb42684fcd
--- /dev/null
+++ b/apply_comprehensive_fix.py
@@ -0,0 +1,66 @@
+import sys
+import re
+
+file_path = 'clang/lib/Sema/SemaTemplate.cpp'
+with open(file_path, 'r') as f:
+    content = f.read()
+
+# 1. Apply Arity Gatekeeper
+gatekeeper = '''  if (Converted.size() < BTD->getTemplateParameters()->size())
+    return QualType();\n\n'''
+func_start_pattern = r'(static QualType 
checkBuiltinTemplateIdType\(.*?TemplateArgumentListInfo\s*&TemplateArgs\)\s*\{)\n'
+content = re.sub(func_start_pattern, r'\1\n' + gatekeeper, content, 
flags=re.DOTALL)
+
+# 2. Fix BTK__make_integer_seq
+make_integer_seq_start = r'case BTK__make_integer_seq: \{\n\s*// 
Specializations of __make_integer_seq<S, T, N> are treated like\n\s*// S<T, 0, 
\.\.\., N-1>\.'
+make_integer_seq_repl = r'''case BTK__make_integer_seq: {
+    assert(Converted.size() == 3);
+    if (Converted[2].isDependent())
+      return QualType();
+
+    // Specializations of __make_integer_seq<S, T, N> are treated like
+    // S<T, 0, ..., N-1>.'''
+content = re.sub(make_integer_seq_start, make_integer_seq_repl, content)
+
+# 3. Fix the integral type check
+integral_check_pattern = r'if \(!OrigType->isIntegralType\(Context\)\) \{'
+integral_check_repl = 'if (!OrigType->isDependentType() && 
!OrigType->isIntegralType(Context)) {'
+content = re.sub(integral_check_pattern, integral_check_repl, content)
+
+# 4. Remove redundant n check
+redundant_n_check = r'TemplateArgument NumArgsArg = Converted\[2\];\n\s*if 
\(NumArgsArg\.isDependent\(\)\)\n\s*return QualType\(\);'
+content = re.sub(redundant_n_check, 'TemplateArgument NumArgsArg = 
Converted[2];', content)
+
+# 5. Fix BTK__type_pack_element
+type_pack_element_start = r'case BTK__type_pack_element: 
\{\n\s*TemplateArgument IndexArg = Converted\[0\], Ts = Converted\[1\];'
+type_pack_element_repl = r'''case BTK__type_pack_element: {
+    assert(Converted.size() == 2 &&
+           "__type_pack_element should be given an index and a parameter 
pack");
+    if (Converted[0].isDependent() || Converted[1].isDependent())
+      return QualType();
+
+    TemplateArgument IndexArg = Converted[0], Ts = Converted[1];'''
+content = re.sub(type_pack_element_start, type_pack_element_repl, content)
+content = re.sub(r'if \(IndexArg\.isDependent\(\) \|\| 
Ts\.isDependent\(\)\)\n\s*return QualType\(\);\n\n', '', content)
+
+# 6. Fix BTK__builtin_common_type
+common_type_start = r'case BTK__builtin_common_type: \{\n\s*if 
\(llvm::any_of\(Converted, \[\]\(auto &C\) \{ return C\.isDependent\(\); 
\}\)\)\n\s*return QualType\(\);'
+common_type_repl = r'''case BTK__builtin_common_type: {
+    assert(Converted.size() == 4);
+    if (Converted[3].isDependent())
+      return QualType();'''
+content = re.sub(common_type_start, common_type_repl, content)
+
+# 7. Fix BTK__hlsl_spirv_type
+spirv_type_start = r'case BTK__hlsl_spirv_type: \{\n\s*if 
\(!Context\.getTargetInfo\(\)\.getTriple\(\)\.isSPIRV\(\)\) \{'
+spirv_type_repl = r'''case BTK__hlsl_spirv_type: {
+    assert(Converted.size() == 4);
+    if (llvm::any_of(Converted, [](const TemplateArgument &A) { return 
A.isDependent(); }))
+      return QualType();
+
+    if (!Context.getTargetInfo().getTriple().isSPIRV()) {'''
+content = re.sub(spirv_type_start, spirv_type_repl, content)
+content = re.sub(r'if \(llvm::any_of\(Converted, \[\]\(auto &C\) \{ return 
C\.isDependent\(\); \}\)\)\n\s*return QualType\(\);\n\n', '', content)
+
+with open(file_path, 'w') as f:
+    f.write(content)
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index fb9202c6d66c8..167bb08f08a0d 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -385,14 +385,17 @@ size_t Pointer::computeOffsetForComparison(const 
ASTContext &ASTCtx) const {
   Pointer P = *this;
   while (true) {
     if (P.isVirtualBaseClass()) {
-      Result += getInlineDesc()->Offset;
+      if (InlineDescriptor *ID = getInlineDesc())
+        Result += ID->Offset;
       P = P.getBase();
       continue;
     }
 
     if (P.isBaseClass()) {
-      if (P.getRecord()->getNumVirtualBases() > 0)
-        Result += P.getInlineDesc()->Offset;
+      if (P.getRecord()->getNumVirtualBases() > 0) {
+        if (InlineDescriptor *ID = P.getInlineDesc())
+          Result += ID->Offset;
+      }
       P = P.getBase();
       continue;
     }
@@ -444,26 +447,41 @@ std::string Pointer::toDiagnosticString(const ASTContext 
&Ctx) const {
   return toAPValue(Ctx).getAsString(Ctx, getType());
 }
 
+bool Pointer::isGlobalInitialized() const {
+  assert(isBlockPointer());
+  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor)) {
+    if (Block *B = block()) {
+      const auto &GD = B->getBlockDesc<GlobalInlineDescriptor>();
+      return GD.InitState == GlobalInitState::Initialized;
+    }
+  }
+  return false;
+}
+
+void Pointer::initializeGlobal() const {
+  assert(isBlockPointer());
+  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor)) {
+    if (Block *B = block()) {
+      auto &GD = B->getBlockDesc<GlobalInlineDescriptor>();
+      GD.InitState = GlobalInitState::Initialized;
+    }
+  }
+}
+
 bool Pointer::isInitialized() const {
   if (!isBlockPointer())
     return true;
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
-    const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
-    return GD.InitState == GlobalInitState::Initialized;
-  }
-
   assert(BS.Pointee && "Cannot check if null pointer was initialized");
   const Descriptor *Desc = getFieldDesc();
   assert(Desc);
   if (Desc->isPrimitiveArray())
     return isElementInitialized(getIndex());
 
-  if (asBlockPointer().Base == 0)
-    return true;
-  // Field has its bit in an inline descriptor.
-  return getInlineDesc()->IsInitialized;
+  if (InlineDescriptor *D = getInlineDesc())
+    return D->IsInitialized;
+
+  return isGlobalInitialized();
 }
 
 bool Pointer::isElementInitialized(unsigned Index) const {
@@ -476,11 +494,8 @@ bool Pointer::isElementInitialized(unsigned Index) const {
   if (isStatic() && BS.Base == 0)
     return true;
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
-    const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
-    return GD.InitState == GlobalInitState::Initialized;
-  }
+  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor))
+    return isGlobalInitialized();
 
   if (Desc->isPrimitiveArray()) {
     InitMapPtr IM = getInitMap();
@@ -525,7 +540,8 @@ void Pointer::startLifetime() const {
     return;
   }
 
-  getInlineDesc()->LifeState = Lifetime::Started;
+  if (InlineDescriptor *ID = getInlineDesc())
+    ID->LifeState = Lifetime::Started;
 }
 
 void Pointer::endLifetime() const {
@@ -545,7 +561,8 @@ void Pointer::endLifetime() const {
     return;
   }
 
-  getInlineDesc()->LifeState = Lifetime::Ended;
+  if (InlineDescriptor *ID = getInlineDesc())
+    ID->LifeState = Lifetime::Ended;
 }
 
 void Pointer::initialize() const {
@@ -554,12 +571,7 @@ void Pointer::initialize() const {
 
   assert(BS.Pointee && "Cannot initialize null pointer");
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
-    auto &GD = BS.Pointee->getBlockDesc<GlobalInlineDescriptor>();
-    GD.InitState = GlobalInitState::Initialized;
-    return;
-  }
+  initializeGlobal();
 
   const Descriptor *Desc = getFieldDesc();
   assert(Desc);
@@ -571,7 +583,12 @@ void Pointer::initialize() const {
 
   // Field has its bit in an inline descriptor.
   assert(BS.Base != 0 && "Only composite fields can be initialised");
-  getInlineDesc()->IsInitialized = true;
+  if (InlineDescriptor *D = getInlineDesc()) {
+    D->IsInitialized = true;
+    return;
+  }
+
+  initializeGlobal();
 }
 
 void Pointer::initializeElement(unsigned Index) const {
@@ -609,11 +626,8 @@ bool Pointer::allElementsInitialized() const {
   if (isStatic() && BS.Base == 0)
     return true;
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
-    const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
-    return GD.InitState == GlobalInitState::Initialized;
-  }
+  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor))
+    return isGlobalInitialized();
 
   InitMapPtr IM = getInitMap();
   return IM.allInitialized();
@@ -626,11 +640,8 @@ bool Pointer::allElementsAlive() const {
   if (isStatic() && BS.Base == 0)
     return true;
 
-  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) &&
-      Offset == BS.Base) {
-    const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>();
-    return GD.InitState == GlobalInitState::Initialized;
-  }
+  if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor))
+    return isGlobalInitialized();
 
   InitMapPtr &IM = getInitMap();
   return IM.allInitialized() || (IM.hasInitMap() && IM->allElementsAlive());
@@ -642,17 +653,26 @@ void Pointer::activate() const {
 
   if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor))
     return;
-  if (!getInlineDesc()->InUnion)
+
+  if (InlineDescriptor *ID = getInlineDesc()) {
+    if (!ID->InUnion)
+      return;
+  } else {
     return;
+  }
 
   std::function<void(Pointer &)> activate;
   activate = [&activate](Pointer &P) -> void {
-    P.getInlineDesc()->IsActive = true;
+    if (InlineDescriptor *ID = P.getInlineDesc())
+      ID->IsActive = true;
+
     if (const Record *R = P.getRecord(); R && !R->isUnion()) {
       for (const Record::Field &F : R->fields()) {
         Pointer FieldPtr = P.atField(F.Offset);
-        if (!FieldPtr.getInlineDesc()->IsActive)
-          activate(FieldPtr);
+        if (InlineDescriptor *ID = FieldPtr.getInlineDesc()) {
+          if (!ID->IsActive)
+            activate(FieldPtr);
+        }
       }
       // FIXME: Bases?
     }
@@ -660,13 +680,16 @@ void Pointer::activate() const {
 
   std::function<void(Pointer &)> deactivate;
   deactivate = [&deactivate](Pointer &P) -> void {
-    P.getInlineDesc()->IsActive = false;
+    if (InlineDescriptor *ID = P.getInlineDesc())
+      ID->IsActive = false;
 
     if (const Record *R = P.getRecord()) {
       for (const Record::Field &F : R->fields()) {
         Pointer FieldPtr = P.atField(F.Offset);
-        if (FieldPtr.getInlineDesc()->IsActive)
-          deactivate(FieldPtr);
+        if (InlineDescriptor *ID = FieldPtr.getInlineDesc()) {
+          if (ID->IsActive)
+            deactivate(FieldPtr);
+        }
       }
       // FIXME: Bases?
     }
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 2515b2fe56ab9..1b00bfd040c00 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -246,7 +246,11 @@ class Pointer {
       return Pointer(Pointee, BS.Base, BS.Base);
 
     // Step into the containing array, if inside one.
-    unsigned Next = BS.Base - getInlineDesc()->Offset;
+    InlineDescriptor *ID = getInlineDesc();
+    if (!ID)
+      return *this;
+
+    unsigned Next = BS.Base - ID->Offset;
     const Descriptor *Desc =
         (Next == Pointee->getDescriptor()->getMetadataSize())
             ? getDeclDesc()
@@ -315,7 +319,14 @@ class Pointer {
       assert(Offset == PastEndMark && "cannot get base of a block");
       return Pointer(BS.Pointee, BS.Base, 0);
     }
-    unsigned NewBase = BS.Base - getInlineDesc()->Offset;
+    if (isRoot())
+      return *this;
+
+    InlineDescriptor *ID = getInlineDesc();
+    if (!ID)
+      return *this;
+
+    unsigned NewBase = BS.Base - ID->Offset;
     return Pointer(BS.Pointee, NewBase, NewBase);
   }
   /// Returns the parent array.
@@ -606,7 +617,7 @@ class Pointer {
     return getSize() / elemSize();
   }
 
-  const Block *block() const { return BS.Pointee; }
+  Block *block() const { return BS.Pointee; }
 
   /// If backed by actual data (i.e. a block pointer), return
   /// an address to that data.
@@ -829,12 +840,19 @@ class Pointer {
   /// Returns the embedded descriptor preceding a field.
   InlineDescriptor *getInlineDesc() const {
     assert(isBlockPointer());
-    assert(BS.Base != sizeof(GlobalInlineDescriptor));
+    if (BS.Base == sizeof(GlobalInlineDescriptor))
+      return nullptr;
+
     assert(BS.Base <= BS.Pointee->getSize());
     assert(BS.Base >= sizeof(InlineDescriptor));
     return getDescriptor(BS.Base);
   }
 
+  /// Returns whether the pointer is a global root and is initialized.
+  bool isGlobalInitialized() const;
+  /// Initializes the global object mentioned by this pointer.
+  void initializeGlobal() const;
+
   /// Returns a descriptor at a given offset.
   InlineDescriptor *getDescriptor(unsigned Offset) const {
     assert(Offset != 0 && "Not a nested pointer");
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3b2c93b9fe7b5..06fa33e5615e8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14337,7 +14337,9 @@ void Sema::ActOnInitializerError(Decl *D) {
       BD->setInvalidDecl();
 
   // Auto types are meaningless if we can't make sense of the initializer.
-  if (VD->getType()->isUndeducedType()) {
+  // Similarly, constexpr variables require a valid constant initializer;
+  // if the initializer is erroneous, the variable is unusable.
+  if (VD->getType()->isUndeducedType() || VD->isConstexpr()) {
     D->setInvalidDecl();
     return;
   }
@@ -14949,9 +14951,11 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl 
*var) {
   QualType baseType = Context.getBaseElementType(type);
   bool HasConstInit = true;
 
-  if (getLangOpts().C23 && var->isConstexpr() && !Init)
+  if (getLangOpts().C23 && var->isConstexpr() && !Init) {
     Diag(var->getLocation(), diag::err_constexpr_var_requires_const_init)
         << var;
+    var->setInvalidDecl();
+  }
 
   // Check whether the initializer is sufficiently constant.
   if ((getLangOpts().CPlusPlus || (getLangOpts().C23 && var->isConstexpr())) &&
@@ -15012,6 +15016,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl 
*var) {
           << var << Init->getSourceRange();
       for (unsigned I = 0, N = Notes.size(); I != N; ++I)
         Diag(Notes[I].first, Notes[I].second);
+      var->setInvalidDecl();
     } else if (GlobalStorage && var->hasAttr<ConstInitAttr>()) {
       auto *Attr = var->getAttr<ConstInitAttr>();
       Diag(var->getLocation(), diag::err_require_constant_init_failed)
diff --git a/clang/test/SemaCXX/constexpr-invalid-initializer.cpp 
b/clang/test/SemaCXX/constexpr-invalid-initializer.cpp
new file mode 100644
index 0000000000000..471bc759a947e
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-invalid-initializer.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 
-fexperimental-new-constant-interpreter %s
+
+// Test that constexpr variables with invalid initializers are marked invalid
+// to prevent crashes in the constant evaluator and bytecode interpreter.
+
+constexpr const int *foo[][2] = { {nullptr, int}, }; // expected-error 
{{expected '(' for function-style cast or type construction}}
+
+// With the fix, the variable is marked invalid, so this static_assert should 
be suppressed.
+static_assert(foo[0][0] == nullptr, ""); 
+
+// Additional test cases
+constexpr int arr[] = {1, int}; // expected-error {{expected '(' for 
function-style cast or type construction}}
diff --git a/final_apply.py b/final_apply.py
new file mode 100644
index 0000000000000..65842747095fb
--- /dev/null
+++ b/final_apply.py
@@ -0,0 +1,66 @@
+import sys
+import os
+import re
+
+file_path = 'clang/lib/Sema/SemaTemplate.cpp'
+with open(file_path, 'r') as f:
+    content = f.read()
+
+# Reset to ensure we are working on a clean slate
+# (The user should have reset origin/main before running this)
+
+# 1. Add Arity Gatekeeper
+gatekeeper = """  if (Converted.size() < BTD->getTemplateParameters()->size())
+    return QualType();\n\n"""
+func_decl = r'(static QualType 
checkBuiltinTemplateIdType\(.*?TemplateArgumentListInfo &TemplateArgs\) \{)\n'
+content = re.sub(func_decl, r'\1\n' + gatekeeper, content, flags=re.DOTALL)
+
+# 2. BTK__make_integer_seq
+# Insert check at the start of case, and remove the internal one.
+make_seq_pattern = r'(case BTK__make_integer_seq: \{)\n'
+make_seq_repl = r'\1\n    assert(Converted.size() == 3);\n    if 
(Converted[2].isDependent())\n      return QualType();\n'
+content = re.sub(make_seq_pattern, make_seq_repl, content)
+
+redundant_n_check = r'if \(NumArgsArg\.isDependent\(\)\)\n\s*return 
QualType\(\);'
+content = re.sub(redundant_n_check, '', content)
+
+# 3. BTK__type_pack_element
+# It already has an assertion. Move the dependent check up.
+# Trunk has: 
+# assert(Converted.size() == 2 && ...);
+# TemplateArgument IndexArg = Converted[0], Ts = Converted[1];
+# if (IndexArg.isDependent() || Ts.isDependent()) return QualType();
+
+# We want it to be:
+# assert(Converted.size() == 2 && ...);
+# if (Converted[0].isDependent() || Converted[1].isDependent()) return 
QualType();
+# TemplateArgument IndexArg = Converted[0], Ts = Converted[1];
+
+type_pack_search = r'case BTK__type_pack_element: 
\{.*?\n\s*assert\(Converted\.size\(\) == 2 &&.*?\);\n\s*'
+type_pack_repl = r'case BTK__type_pack_element: {\n    assert(Converted.size() 
== 2 &&\n           "__type_pack_element should be given an index and a 
parameter pack");\n    if (Converted[0].isDependent() || 
Converted[1].isDependent())\n      return QualType();\n\n'
+content = re.sub(r'case BTK__type_pack_element: 
\{.*?assert\(Converted\.size\(\) == 2 &&.*?\);\s*', type_pack_repl, content, 
flags=re.DOTALL)
+
+# Remove the now-redundant assignment if it followed immediately
+content = re.sub(r'TemplateArgument IndexArg = Converted\[0\], Ts = 
Converted\[1\];\n\s*if \(IndexArg\.isDependent\(\) \|\| 
Ts\.isDependent\(\)\)\n\s*return QualType\(\);', 'TemplateArgument IndexArg = 
Converted[0], Ts = Converted[1];', content)
+
+# 4. BTK__builtin_common_type
+# Trunk has: 
+# assert(Converted.size() == 4);
+# if (llvm::any_of(Converted, ...)) return QualType();
+# We change it to only check Converted[3].
+content = re.sub(r'if \(llvm::any_of\(Converted, \[\]\(auto &C\) \{ return 
C\.isDependent\(\); \}\)\)\n\s*return QualType\(\);', 'if 
(Converted[3].isDependent())\n      return QualType();', content, count=1)
+
+# 5. BTK__hlsl_spirv_type
+# Trunk has any_of. We keep it but ensure it's at the top of the case area.
+# Wait, I already removed one any_of. Let's find the second one.
+# Actually, I'll just be explicit.
+spirv_search = r'case BTK__hlsl_spirv_type: 
\{.*?\n\s*assert\(Converted\.size\(\) == 4\);'
+spirv_repl = r'case BTK__hlsl_spirv_type: {\n    assert(Converted.size() == 
4);\n    if (llvm::any_of(Converted, [](const TemplateArgument &A) { return 
A.isDependent(); }))\n      return QualType();\n\n'
+content = re.sub(spirv_search, spirv_repl, content, flags=re.DOTALL)
+
+# Cleanup any remaining any_of in hlsl case
+content = re.sub(r'if \(llvm::any_of\(Converted, \[\]\(auto &C\) \{ return 
C\.isDependent\(\); \}\)\)\n\s*return QualType\(\);', '', content)
+
+with open(file_path, 'w') as f:
+    f.write(content)
+print("Applied successfully.")
diff --git a/final_apply_perfect.py b/final_apply_perfect.py
new file mode 100644
index 0000000000000..d6f5a0f50aeac
--- /dev/null
+++ b/final_apply_perfect.py
@@ -0,0 +1,105 @@
+import sys
+import os
+
+file_path = 'clang/lib/Sema/SemaTemplate.cpp'
+
+# Read the original file from git to ensure a clean base
+os.system(f'git checkout {file_path}')
+
+with open(file_path, 'r') as f:
+    lines = f.readlines()
+
+new_lines = []
+skip_until = None
+
+i = 0
+while i < len(lines):
+    line = lines[i]
+    
+    # 1. Insert Smart Gatekeeper at the beginning of checkBuiltinTemplateIdType
+    if 'static QualType checkBuiltinTemplateIdType(' in line:
+        new_lines.append(line)
+        while 'TemplateArgumentListInfo &TemplateArgs) {' not in lines[i]:
+            i += 1
+            new_lines.append(lines[i])
+        new_lines.append('  TemplateParameterList *Params = 
BTD->getTemplateParameters();\n')
+        new_lines.append('  unsigned RequiredArgs = Params->size();\n')
+        new_lines.append('  if (Params->hasParameterPack()) {\n')
+        new_lines.append('    if (Converted.size() < RequiredArgs)\n')
+        new_lines.append('      return QualType();\n')
+        new_lines.append('  } else {\n')
+        new_lines.append('    if (Converted.size() != RequiredArgs)\n')
+        new_lines.append('      return QualType();\n')
+        new_lines.append('  }\n\n')
+        i += 1
+        continue
+
+    # 2. __make_integer_seq: early isDependent check
+    if 'case BTK__make_integer_seq: {' in line:
+        new_lines.append(line)
+        new_lines.append('    if (Converted[2].isDependent())\n')
+        new_lines.append('      return QualType();\n')
+        i += 1
+        continue
+
+    # 3. Handle OrigType->isIntegralType(Context) check to include 
!OrigType->isDependentType()
+    if 'if (!OrigType->isIntegralType(Context)) {' in line:
+        new_lines.append('    if (!OrigType->isDependentType() && 
!OrigType->isIntegralType(Context)) {\n')
+        i += 1
+        continue
+
+    # 4. Remove the redundant NumArgsArg.isDependent check lower down (if it 
exists in trunk)
+    # Trunk usually doesn't have it, but we'll be safe.
+    
+    new_lines.append(line)
+    i += 1
+
+with open(file_path, 'w') as f:
+    f.writelines(new_lines)
+
+# Apply the test file fix
+test_file = 'clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp'
+test_content = '''// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-error@* 2 {{template argument for non-type template parameter must 
be an expression}}
+
+using SizeT = decltype(sizeof(int));
+
+// Dependent cases that previously crashed but now return QualType() 
gracefully.
+template <SizeT... Seq> // expected-note {{template parameter is declared 
here}}
+using gh180307 = __type_pack_element<Seq...>;
+
+template <typename T>
+using gh180307_bis = __make_integer_seq<gh180307, T>;
+// expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
+
+// Eager expansion checks: Built-in templates should expand even if the
+// destination template OR the type argument is dependent, provided the size 
is known.
+template <template <typename T, T... Ints> class Seq>
+using test_make_integer_seq_eager = __make_integer_seq<Seq, int, 2>;
+
+template <typename T, T... Ints> struct MySeq;
+using check_eager = test_make_integer_seq_eager<MySeq>;
+using check_eager = MySeq<int, 0, 1>;
+
+template <typename T>
+using test_make_integer_seq_type_dependent = __make_integer_seq<MySeq, T, 2>;
+using check_type_eager = test_make_integer_seq_type_dependent<int>;
+using check_type_eager = MySeq<int, 0, 1>;
+
+// Too many arguments tests
+template <int N> struct S; // expected-note {{template parameter is declared 
here}}
+using too_many_args = __make_integer_seq<S, int, 10, int>; 
+// expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
+
+// Too few arguments tests
+template <SizeT Index>
+using too_few_args = __type_pack_element<Index>;
+
+// Verify that too_few_args doesn't crash on instantiation either
+// (It should just be an invalid type)
+template <SizeT I> struct Wrap {
+  using type = too_few_args<I>;
+};
+'''
+with open(test_file, 'w') as f:
+    f.write(test_content)
diff --git a/final_logic_fix.py b/final_logic_fix.py
new file mode 100644
index 0000000000000..1d9fe68b15567
--- /dev/null
+++ b/final_logic_fix.py
@@ -0,0 +1,20 @@
+import sys
+import re
+
+file_path = 'clang/lib/Sema/SemaTemplate.cpp'
+with open(file_path, 'r') as f:
+    content = f.read()
+
+# 1. Refine BTK__make_integer_seq: Only bail if N (Converted[2]) is dependent.
+pattern1 = r'if \(Converted\[1\]\.isDependent\(\) \|\| 
Converted\[2\]\.isDependent\(\)\)\s*return QualType\(\);'
+content = re.sub(pattern1, 'if (Converted[2].isDependent())\n      return 
QualType();', content)
+
+# 2. Remove the assertion that OrigType is not dependent
+content = content.replace('    assert(!OrigType->isDependentType());\n', '')
+
+# 3. Add a check for IntegralType ONLY if it is NOT dependent
+pattern2 = r'if \(!OrigType->isIntegralType\(Context\)\) \{'
+content = re.sub(pattern2, 'if (!OrigType->isDependentType() && 
!OrigType->isIntegralType(Context)) {', content)
+
+with open(file_path, 'w') as f:
+    f.write(content)
diff --git a/repro_180251.c b/repro_180251.c
new file mode 100644
index 0000000000000..c1f3f1be56988
--- /dev/null
+++ b/repro_180251.c
@@ -0,0 +1,15 @@
+typedef signed char int8_t;
+typedef int int32_t;
+
+int32_t g_3, g_5;
+extern int printf(const char *, ...);
+
+int main() {
+    int8_t l_2[6];
+    for (g_3 = 0; g_3 < 6; g_3 += 1)
+        l_2[g_3] = 7;
+    for (g_3 = 5; g_3 >= 0; g_3 -= 1)
+        g_5 ^= l_2[g_3];
+    printf("checksum = %08X\n", g_5);
+    return 0;
+}
diff --git a/repro_180251.ll b/repro_180251.ll
new file mode 100644
index 0000000000000..e2415e54a4dd3
--- /dev/null
+++ b/repro_180251.ll
@@ -0,0 +1,107 @@
+; ModuleID = 'repro_180251.c'
+source_filename = "repro_180251.c"
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "aarch64-unknown-linux-gnu"
+
+@g_3 = dso_local local_unnamed_addr global i32 0, align 4
+@g_5 = dso_local local_unnamed_addr global i32 0, align 4
[email protected] = private unnamed_addr constant [17 x i8] c"checksum = %08X\0A\00", 
align 1
+
+; Function Attrs: nofree nounwind optsize sspstrong uwtable vscale_range(1,16)
+define dso_local noundef i32 @main() local_unnamed_addr #0 {
+  %1 = alloca [6 x i8], align 1
+  call void @llvm.lifetime.start.p0(i64 6, ptr nonnull %1) #7
+  call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(6) 
%1, i8 7, i64 6, i1 false), !tbaa !6
+  %2 = load i32, ptr @g_5, align 4, !tbaa !9
+  %3 = tail call i64 @llvm.vscale.i64()
+  %4 = shl nuw nsw i64 %3, 2
+  %5 = insertelement <vscale x 4 x i32> zeroinitializer, i32 %2, i64 0
+  %6 = tail call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 
0, i64 6)
+  %7 = sub nsw i64 1, %4
+  %8 = getelementptr i8, ptr %1, i64 %7
+  br label %9
+
+9:                                                ; preds = %9, %0
+  %10 = phi i64 [ 0, %0 ], [ %21, %9 ]
+  %11 = phi <vscale x 4 x i1> [ %6, %0 ], [ %22, %9 ]
+  %12 = phi <vscale x 4 x i32> [ %5, %0 ], [ %20, %9 ]
+  %13 = sub i64 5, %10
+  %14 = getelementptr [6 x i8], ptr %8, i64 0, i64 %13
+  %15 = tail call <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x 
i1> %11)
+  %16 = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr %14, i32 1, 
<vscale x 4 x i1> %15, <vscale x 4 x i8> poison), !tbaa !6
+  %17 = tail call <vscale x 4 x i8> @llvm.vector.reverse.nxv4i8(<vscale x 4 x 
i8> %16)
+  %18 = sext <vscale x 4 x i8> %17 to <vscale x 4 x i32>
+  %19 = select <vscale x 4 x i1> %11, <vscale x 4 x i32> %18, <vscale x 4 x 
i32> zeroinitializer
+  %20 = xor <vscale x 4 x i32> %12, %19
+  %21 = add i64 %10, %4
+  %22 = tail call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 
%21, i64 6)
+  %23 = extractelement <vscale x 4 x i1> %22, i64 0
+  br i1 %23, label %9, label %24, !llvm.loop !11
+
+24:                                               ; preds = %9
+  %25 = tail call i32 @llvm.vector.reduce.xor.nxv4i32(<vscale x 4 x i32> %20)
+  store i32 -1, ptr @g_3, align 4, !tbaa !9
+  store i32 %25, ptr @g_5, align 4, !tbaa !9
+  %26 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull 
dereferenceable(1) @.str, i32 noundef %25) #8
+  call void @llvm.lifetime.end.p0(i64 6, ptr nonnull %1) #7
+  ret i32 0
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn 
memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #1
+
+; Function Attrs: nofree nounwind optsize
+declare noundef i32 @printf(ptr noundef readonly captures(none), ...) 
local_unnamed_addr #2
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn 
memory(argmem: readwrite)
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr captures(none)) #1
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
+declare void @llvm.memset.p0.i64(ptr writeonly captures(none), i8, i64, i1 
immarg) #3
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare i64 @llvm.vscale.i64() #4
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64, i64) #4
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x i1>) #4
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: 
read)
+declare <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr captures(none), i32 
immarg, <vscale x 4 x i1>, <vscale x 4 x i8>) #5
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare <vscale x 4 x i8> @llvm.vector.reverse.nxv4i8(<vscale x 4 x i8>) #4
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn 
memory(none)
+declare i32 @llvm.vector.reduce.xor.nxv4i32(<vscale x 4 x i32>) #6
+
+attributes #0 = { nofree nounwind optsize sspstrong uwtable vscale_range(1,16) 
"frame-pointer"="non-leaf" "no-trapping-math"="true" 
"stack-protector-buffer-size"="8" "target-cpu"="generic" 
"target-features"="+bti,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fullfp16,+jsconv,+lse,+neon,+pauth,+predres,+ras,+rcpc,+rdm,+sb,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+v9a,-fmv"
 }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn 
memory(argmem: readwrite) }
+attributes #2 = { nofree nounwind optsize "frame-pointer"="non-leaf" 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="generic" 
"target-features"="+bti,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fullfp16,+jsconv,+lse,+neon,+pauth,+predres,+ras,+rcpc,+rdm,+sb,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+v9a,-fmv"
 }
+attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
+attributes #4 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #5 = { nocallback nofree nosync nounwind willreturn memory(argmem: 
read) }
+attributes #6 = { nocallback nofree nosync nounwind speculatable willreturn 
memory(none) }
+attributes #7 = { nounwind }
+attributes #8 = { optsize }
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4}
+!llvm.ident = !{!5}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{i32 7, !"frame-pointer", i32 1}
+!5 = !{!"clang version 21.1.6"}
+!6 = !{!7, !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
+!9 = !{!10, !10, i64 0}
+!10 = !{!"int", !7, i64 0}
+!11 = distinct !{!11, !12, !13, !14}
+!12 = !{!"llvm.loop.mustprogress"}
+!13 = !{!"llvm.loop.isvectorized", i32 1}
+!14 = !{!"llvm.loop.unroll.runtime.disable"}
diff --git a/repro_180307.cpp b/repro_180307.cpp
new file mode 100644
index 0000000000000..0b539d7af1786
--- /dev/null
+++ b/repro_180307.cpp
@@ -0,0 +1,3 @@
+namespace std { typedef decltype(sizeof(0)) size_t; }
+template <std::size_t... Seq> void f(__type_pack_element<Seq...>) {}
+int main() {}
diff --git a/repro_bytecode.cpp b/repro_bytecode.cpp
new file mode 100644
index 0000000000000..311c7c4bf5b00
--- /dev/null
+++ b/repro_bytecode.cpp
@@ -0,0 +1,13 @@
+#include <stdint.h>
+
+constexpr int32_t fix() {
+    int32_t g_5 = 0;
+    int8_t l_2[6];
+    for (int32_t g_3 = 0; g_3 < 6; g_3 += 1)
+        l_2[g_3] = 7;
+    for (int32_t g_3 = 5; g_3 >= 0; g_3 -= 1)
+        g_5 ^= l_2[g_3];
+    return g_5;
+}
+
+static_assert(fix() == 0, "");
diff --git a/repro_const_crash.cpp b/repro_const_crash.cpp
new file mode 100644
index 0000000000000..5410e4feac8b1
--- /dev/null
+++ b/repro_const_crash.cpp
@@ -0,0 +1,2 @@
+const int a = (1/0); // Division by zero error
+int arr[a];
diff --git a/repro_no_init.cpp b/repro_no_init.cpp
new file mode 100644
index 0000000000000..1dcf28122b5d8
--- /dev/null
+++ b/repro_no_init.cpp
@@ -0,0 +1,2 @@
+constexpr int x; // error: must have initializer
+int y = x;
diff --git a/repro_non_constexpr.cpp b/repro_non_constexpr.cpp
new file mode 100644
index 0000000000000..b73db5ee83bbe
--- /dev/null
+++ b/repro_non_constexpr.cpp
@@ -0,0 +1 @@
+int *foo[][2] = { {nullptr, int}, };
diff --git a/repro_normal.cpp b/repro_normal.cpp
new file mode 100644
index 0000000000000..55d546e73db28
--- /dev/null
+++ b/repro_normal.cpp
@@ -0,0 +1 @@
+int x = int;
diff --git a/repro_ptrmem_array.cpp b/repro_ptrmem_array.cpp
new file mode 100644
index 0000000000000..8857a2ab642d8
--- /dev/null
+++ b/repro_ptrmem_array.cpp
@@ -0,0 +1,7 @@
+struct C { int c; };
+constexpr int f() {
+  C carray[1] = {{1}};
+  int C::* p = &C::c;
+  return carray[0].*p;
+}
+static_assert(f() == 1, "");
diff --git a/repro_ptrmem_array_records.cpp b/repro_ptrmem_array_records.cpp
new file mode 100644
index 0000000000000..8ec87a665f84f
--- /dev/null
+++ b/repro_ptrmem_array_records.cpp
@@ -0,0 +1,10 @@
+struct B { int b; };
+struct C : B { int c; };
+
+constexpr int f() {
+  B b_array[1] = {{1}};
+  int C::* p = &C::c;
+  int B::* p2 = (int B::*)p;
+  return b_array[0].*p2;
+}
+static_assert(f() == 1, "");
diff --git a/repro_ptrmem_crash.cpp b/repro_ptrmem_crash.cpp
new file mode 100644
index 0000000000000..67b708bdadefa
--- /dev/null
+++ b/repro_ptrmem_crash.cpp
@@ -0,0 +1,11 @@
+struct A { int a; };
+struct B { int b; };
+struct C : A, B { int c; };
+
+constexpr int f() {
+  int C::* p = &C::c;
+  int B::* p2 = (int B::*)p;
+  B b = {1};
+  return b.*p2;
+}
+static_assert(f() == 1, "");
diff --git a/repro_ptrmem_multi_array.cpp b/repro_ptrmem_multi_array.cpp
new file mode 100644
index 0000000000000..d5a34139c5a11
--- /dev/null
+++ b/repro_ptrmem_multi_array.cpp
@@ -0,0 +1,11 @@
+struct A { int a; };
+struct B { int b; };
+struct C : A, B { int c; };
+
+constexpr int f() {
+  B b_array[1] = {{1}};
+  int C::* p = &C::c;
+  int B::* p2 = (int B::*)p;
+  return b_array[0].*p2;
+}
+static_assert(f() == 1, "");
diff --git a/repro_scalar.cpp b/repro_scalar.cpp
new file mode 100644
index 0000000000000..b33d459688406
--- /dev/null
+++ b/repro_scalar.cpp
@@ -0,0 +1 @@
+constexpr int x = int;
diff --git a/test-invalid-constexpr.cpp b/test-invalid-constexpr.cpp
new file mode 100644
index 0000000000000..2dd10750e66ef
--- /dev/null
+++ b/test-invalid-constexpr.cpp
@@ -0,0 +1,2 @@
+constexpr const int *foo[][2] = { {nullptr, int}, };
+static_assert(foo[0][0] == nullptr, "");
diff --git a/test.cpp b/test.cpp
new file mode 100644
index 0000000000000..eb58768a121e3
--- /dev/null
+++ b/test.cpp
@@ -0,0 +1 @@
+constexpr int x;
diff --git a/test2.cpp b/test2.cpp
new file mode 100644
index 0000000000000..f6269dfcfe76e
--- /dev/null
+++ b/test2.cpp
@@ -0,0 +1 @@
+constexpr const int *foo[][2];
diff --git a/test3.cpp b/test3.cpp
new file mode 100644
index 0000000000000..6723bac6f45d3
--- /dev/null
+++ b/test3.cpp
@@ -0,0 +1 @@
+const int foo[] = {1, int};
diff --git a/test_crash.cpp b/test_crash.cpp
new file mode 100644
index 0000000000000..5045f9a71a59b
--- /dev/null
+++ b/test_crash.cpp
@@ -0,0 +1,12 @@
+
+constexpr int fix() {
+    int g_5 = 0;
+    char l_2[6];
+    for (int g_3 = 0; g_3 < 6; g_3 += 1)
+        l_2[g_3] = 7;
+    for (int g_3 = 5; g_3 >= 0; g_3 -= 1)
+        g_5 ^= l_2[g_3];
+    return g_5;
+}
+
+static_assert(fix() == 0, "");
diff --git a/test_masking.cpp b/test_masking.cpp
new file mode 100644
index 0000000000000..5530452bcd18f
--- /dev/null
+++ b/test_masking.cpp
@@ -0,0 +1,2 @@
+constexpr int x = error;
+int y = x + 1; // Does this still show an error if x is invalid?
diff --git a/test_no_init.cpp b/test_no_init.cpp
new file mode 100644
index 0000000000000..ab15dcec2fdde
--- /dev/null
+++ b/test_no_init.cpp
@@ -0,0 +1 @@
+constexpr const int *foo[][2]; static_assert(foo[0][0] == nullptr, "");
diff --git a/test_output.txt b/test_output.txt
new file mode 100644
index 0000000000000..05bce1f83014e
--- /dev/null
+++ b/test_output.txt
@@ -0,0 +1,10 @@
+error: 'expected-error' diagnostics expected but not seen: 
+  File clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Line 19: 
too few template arguments for class template '__make_integer_seq'
+  File clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Line 20: 
too few template arguments for class template '__builtin_common_type'
+  File clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Line 28 
(directive at clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp:29): 
too few template arguments for class template '__make_integer_seq'
+error: 'expected-error' diagnostics seen but not expected: 
+  File clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Line 12: 
template argument for template template parameter must be a class template or 
type alias template
+  File clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Line 15: 
template argument for template template parameter must be a class template or 
type alias template
+  File clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Line 19: 
template argument for template template parameter must be a class template or 
type alias template
+  (frontend): template argument for non-type template parameter must be an 
expression
+7 errors generated.
diff --git a/test_pm.cpp b/test_pm.cpp
new file mode 100644
index 0000000000000..a5bf681e408d6
--- /dev/null
+++ b/test_pm.cpp
@@ -0,0 +1,2 @@
+struct S { int a; };
+static_assert(&S::a + 1, "");
\ No newline at end of file

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

Reply via email to