https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/192206

E.g. for

```c++
constexpr int unInitLocal() {
  int a;
  return a; // both-note {{read of uninitialized object}}
}
static_assert(unInitLocal() == 0, ""); // both-error {{not an integral constant 
expression}} \
                                       // both-note {{in call to 
'unInitLocal()'}}
```

we now diagnose:
```console
array.cpp:896:15: error: static assertion expression is not an integral 
constant expression
  896 | static_assert(unInitLocal() == 0, ""); // both-error {{not an integral 
constant expression}} \
      |               ^~~~~~~~~~~~~~~~~~
array.cpp:894:10: note: read of uninitialized object is not allowed in a 
constant expression
  894 |   return a; // both-note {{read of uninitialized object}}
      |          ^
array.cpp:896:15: note: in call to 'unInitLocal()'
  896 | static_assert(unInitLocal() == 0, ""); // both-error {{not an integral 
constant expression}} \
      |               ^~~~~~~~~~~~~
array.cpp:893:7: note: declared here
  893 |   int a;
      |       ^
1 warning and 1 error generated.
```
and point at the object that we were trying to read from. This adds an 
`NoteLValueLocation()` call to the emission of `note_constexpr_access_uninit`, 
which is already done in other places:

https://github.com/llvm/llvm-project/blob/7ae5fe63dd979eae13ea04e166f94056ec1306ca/clang/lib/AST/ExprConstant.cpp#L4565-L4570

>From 2f99d81347c73d08af896de4b755f9ce43f186ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Wed, 15 Apr 2026 09:55:41 +0200
Subject: [PATCH] [clang][ExprConst]

---
 clang/lib/AST/ByteCode/Interp.cpp             | 60 +++++++++++--------
 clang/lib/AST/ByteCode/Interp.h               |  5 +-
 clang/lib/AST/ExprConstant.cpp                |  4 +-
 .../ByteCode/builtin-bit-cast-bitfields.cpp   | 10 ++--
 .../ByteCode/builtin-bit-cast-long-double.cpp |  2 +-
 clang/test/AST/ByteCode/builtin-functions.cpp |  2 +-
 clang/test/AST/ByteCode/constexpr-nqueens.cpp |  4 +-
 clang/test/AST/ByteCode/cxx11.cpp             |  3 +-
 clang/test/AST/ByteCode/cxx17.cpp             |  3 +-
 clang/test/AST/ByteCode/cxx20.cpp             | 21 ++++---
 clang/test/AST/ByteCode/cxx2a.cpp             |  3 +-
 clang/test/AST/ByteCode/lifetimes.cpp         |  6 +-
 clang/test/AST/ByteCode/lifetimes26.cpp       |  8 +--
 clang/test/AST/ByteCode/literals.cpp          |  2 +-
 clang/test/AST/ByteCode/new-delete.cpp        | 11 ++--
 clang/test/AST/ByteCode/placement-new.cpp     |  9 +--
 clang/test/AST/ByteCode/records.cpp           |  2 +-
 clang/test/AST/ByteCode/unions.cpp            |  4 +-
 clang/test/C/C23/n3006.c                      |  5 +-
 clang/test/CXX/drs/cwg2026.cpp                |  6 ++
 clang/test/CXX/drs/cwg3xx.cpp                 |  1 +
 clang/test/CXX/expr/expr.const/p2-0x.cpp      |  2 +-
 clang/test/Sema/constexpr.c                   |  5 +-
 .../SemaCXX/builtin-is-within-lifetime.cpp    |  6 +-
 .../SemaCXX/constant-expression-cxx11.cpp     | 31 ++++++----
 .../SemaCXX/constant-expression-cxx14.cpp     | 23 ++++---
 .../SemaCXX/constant-expression-cxx2a.cpp     | 29 +++++----
 .../SemaCXX/constexpr-builtin-bit-cast.cpp    |  6 +-
 clang/test/SemaCXX/constexpr-printing.cpp     |  4 +-
 clang/test/SemaCXX/constexpr-value-init.cpp   | 20 +++++--
 .../test/SemaCXX/cxx2a-constexpr-dynalloc.cpp |  6 +-
 .../SemaCXX/cxx2c-constexpr-placement-new.cpp |  4 +-
 clang/test/SemaCXX/static-assert-cxx26.cpp    |  2 +-
 33 files changed, 188 insertions(+), 121 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index abcf55bfa670d..5bc1067518558 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -83,6 +83,17 @@ static void diagnoseMissingInitializer(InterpState &S, 
CodePtr OpPC,
   S.Note(VD->getLocation(), diag::note_declared_at) << VD->getSourceRange();
 }
 
+static void noteValueLocation(InterpState &S, const Block *B) {
+  const Descriptor *Desc = B->getDescriptor();
+
+  if (B->isDynamic())
+    S.Note(Desc->getLocation(), diag::note_constexpr_dynamic_alloc_here);
+  else if (B->isTemporary())
+    S.Note(Desc->getLocation(), diag::note_constexpr_temporary_here);
+  else
+    S.Note(Desc->getLocation(), diag::note_declared_at);
+}
+
 static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC,
                                      const ValueDecl *VD);
 static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC,
@@ -185,8 +196,7 @@ static bool CheckTemporary(InterpState &S, CodePtr OpPC, 
const Block *B,
         !MTE->isUsableInConstantExpressions(S.getASTContext())) {
       const SourceInfo &E = S.Current->getSource(OpPC);
       S.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
-      S.Note(B->getDescriptor()->getLocation(),
-             diag::note_constexpr_temporary_here);
+      noteValueLocation(S, B);
       return false;
     }
   }
@@ -418,14 +428,9 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer 
&Ptr,
     if (Ptr.isDynamic()) {
       S.FFDiag(Src, diag::note_constexpr_access_deleted_object) << AK;
     } else if (!S.checkingPotentialConstantExpression()) {
-      bool IsTemp = Ptr.isTemporary();
       S.FFDiag(Src, diag::note_constexpr_access_uninit)
           << AK << /*uninitialized=*/false << S.Current->getRange(OpPC);
-
-      if (IsTemp)
-        S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
-      else
-        S.Note(Ptr.getDeclLoc(), diag::note_declared_at);
+      noteValueLocation(S, Ptr.block());
     }
 
     return false;
@@ -648,14 +653,16 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, 
const Pointer &Ptr,
                            AccessKinds AK) {
   assert(Ptr.isLive());
   assert(!Ptr.isInitialized());
-  return DiagnoseUninitialized(S, OpPC, Ptr.isExtern(), Ptr.getDeclDesc(), AK);
+  return DiagnoseUninitialized(S, OpPC, Ptr.isExtern(), Ptr.block(), AK);
 }
 
 bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, bool Extern,
-                           const Descriptor *Desc, AccessKinds AK) {
+                           const Block *B, AccessKinds AK) {
   if (Extern && S.checkingPotentialConstantExpression())
     return false;
 
+  const Descriptor *Desc = B->getDescriptor();
+
   if (const auto *VD = Desc->asVarDecl();
       VD && (VD->isConstexpr() || VD->hasGlobalStorage())) {
 
@@ -670,6 +677,7 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, 
bool Extern,
         // Diagnose as "read of object outside its lifetime".
         S.FFDiag(Loc, diag::note_constexpr_access_uninit)
             << AK << /*IsIndeterminate=*/false;
+        S.Note(VD->getLocation(), diag::note_declared_at);
       }
       return false;
     }
@@ -687,21 +695,27 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, 
bool Extern,
   if (!S.checkingPotentialConstantExpression()) {
     S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit)
         << AK << /*uninitialized=*/true << S.Current->getRange(OpPC);
+    noteValueLocation(S, B);
   }
   return false;
 }
 
 static bool CheckLifetime(InterpState &S, CodePtr OpPC, Lifetime LT,
-                          AccessKinds AK) {
+                          const Block *B, AccessKinds AK) {
   if (LT == Lifetime::Started)
     return true;
 
   if (!S.checkingPotentialConstantExpression()) {
     S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit)
         << AK << /*uninitialized=*/false << S.Current->getRange(OpPC);
+    noteValueLocation(S, B);
   }
   return false;
 }
+static bool CheckLifetime(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
+                          AccessKinds AK) {
+  return CheckLifetime(S, OpPC, Ptr.getLifetime(), Ptr.block(), AK);
+}
 
 static bool CheckWeak(InterpState &S, CodePtr OpPC, const Block *B) {
   if (!B->isWeak())
@@ -733,8 +747,7 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const 
Block *B) {
   if (!CheckConstant(S, OpPC, B->getDescriptor()))
     return false;
   if (Desc.InitState != GlobalInitState::Initialized)
-    return DiagnoseUninitialized(S, OpPC, B->isExtern(), B->getDescriptor(),
-                                 AK_Read);
+    return DiagnoseUninitialized(S, OpPC, B->isExtern(), B, AK_Read);
   if (!CheckTemporary(S, OpPC, B, AK_Read))
     return false;
   if (B->getDescriptor()->IsVolatile) {
@@ -755,11 +768,10 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const 
Block *B) {
 bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) {
   assert(!B->isExtern());
   const auto &Desc = *reinterpret_cast<const InlineDescriptor *>(B->rawData());
-  if (!CheckLifetime(S, OpPC, Desc.LifeState, AK_Read))
+  if (!CheckLifetime(S, OpPC, Desc.LifeState, B, AK_Read))
     return false;
   if (!Desc.IsInitialized)
-    return DiagnoseUninitialized(S, OpPC, /*Extern=*/false, B->getDescriptor(),
-                                 AK_Read);
+    return DiagnoseUninitialized(S, OpPC, /*Extern=*/false, B, AK_Read);
   if (B->getDescriptor()->IsVolatile) {
     if (!S.getLangOpts().CPlusPlus)
       return Invalid(S, OpPC);
@@ -805,7 +817,7 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer 
&Ptr,
     return false;
   if (!CheckActive(S, OpPC, Ptr, AK))
     return false;
-  if (!CheckLifetime(S, OpPC, Ptr.getLifetime(), AK))
+  if (!CheckLifetime(S, OpPC, Ptr, AK))
     return false;
   if (!Ptr.isInitialized())
     return DiagnoseUninitialized(S, OpPC, Ptr, AK);
@@ -843,7 +855,7 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
 
   if (!CheckActive(S, OpPC, Ptr, AK_Read))
     return false;
-  if (!CheckLifetime(S, OpPC, Ptr.getLifetime(), AK_Read))
+  if (!CheckLifetime(S, OpPC, Ptr, AK_Read))
     return false;
   if (!Ptr.isInitialized())
     return DiagnoseUninitialized(S, OpPC, Ptr, AK_Read);
@@ -868,7 +880,7 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer 
&Ptr,
       return false;
     return CheckDummy(S, OpPC, Ptr.block(), AK_Assign);
   }
-  if (!CheckLifetime(S, OpPC, Ptr.getLifetime(), AK_Assign))
+  if (!CheckLifetime(S, OpPC, Ptr, AK_Assign))
     return false;
   if (!CheckRange(S, OpPC, Ptr, AK_Assign))
     return false;
@@ -1138,11 +1150,7 @@ bool CheckDeleteSource(InterpState &S, CodePtr OpPC, 
const Expr *Source,
   const SourceInfo &Loc = S.Current->getSource(OpPC);
   S.FFDiag(Loc, diag::note_constexpr_delete_not_heap_alloc)
       << Ptr.toDiagnosticString(S.getASTContext());
-
-  if (Ptr.isTemporary())
-    S.Note(Ptr.getDeclLoc(), diag::note_constexpr_temporary_here);
-  else
-    S.Note(Ptr.getDeclLoc(), diag::note_declared_at);
+  noteValueLocation(S, Ptr.block());
   return false;
 }
 
@@ -1505,7 +1513,7 @@ bool CheckDestructor(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
     return false;
   if (!CheckRange(S, OpPC, Ptr, AK_Destroy))
     return false;
-  if (!CheckLifetime(S, OpPC, Ptr.getLifetime(), AK_Destroy))
+  if (!CheckLifetime(S, OpPC, Ptr, AK_Destroy))
     return false;
 
   // Can't call a dtor on a global variable.
@@ -2028,7 +2036,7 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, 
const Expr *E,
 
   // CheckLifetime for this and all base pointers.
   for (Pointer P = Ptr;;) {
-    if (!CheckLifetime(S, OpPC, P.getLifetime(), AK_Construct))
+    if (!CheckLifetime(S, OpPC, P, AK_Construct))
       return false;
 
     if (P.isRoot())
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 99651ca98ea6d..ea94df2c90187 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -82,7 +82,7 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr);
 bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
                            AccessKinds AK);
 bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, bool Extern,
-                           const Descriptor *Desc, AccessKinds AK);
+                           const Block *B, AccessKinds AK);
 
 /// Checks a direct load of a primitive value from a global or local variable.
 bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B);
@@ -1663,8 +1663,7 @@ bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, 
uint32_t I) {
   const Block *B = S.P.getGlobal(I);
   const auto &Desc = B->getBlockDesc<GlobalInlineDescriptor>();
   if (Desc.InitState != GlobalInitState::Initialized)
-    return DiagnoseUninitialized(S, OpPC, B->isExtern(), B->getDescriptor(),
-                                 AK_Read);
+    return DiagnoseUninitialized(S, OpPC, B->isExtern(), B, AK_Read);
 
   S.Stk.push<T>(B->deref<T>());
   return true;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4f45fa728c605..a185f1b631cf8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4180,10 +4180,12 @@ findSubobject(EvalInfo &Info, const Expr *E, const 
CompleteObject &Obj,
       // IsWithinLifetime, resulting in false.
       if (I != 0 && handler.AccessKind == AK_IsWithinLifetime)
         return false;
-      if (!Info.checkingPotentialConstantExpression())
+      if (!Info.checkingPotentialConstantExpression()) {
         Info.FFDiag(E, diag::note_constexpr_access_uninit)
             << handler.AccessKind << O->isIndeterminate()
             << E->getSourceRange();
+        NoteLValueLocation(Info, Obj.Base);
+      }
       return handler.failed();
     }
 
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp 
b/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp
index 5aa4e256e4638..2eefa138f7f0a 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp
@@ -156,8 +156,9 @@ namespace BitFields {
 
     static_assert(f()[0] + f()[1] + f()[2] == 0xc0 + 0xff + 0xee);
     {
-      // expected-error@+2 {{initialized by a constant expression}}
-      // expected-note@+1 {{in call to}}
+      // expected-error@+3 {{initialized by a constant expression}}
+      // expected-note@+2 {{in call to}}
+      // expected-note@+1 {{temporary created here}}
       constexpr auto _bad = f()[3];
     }
 
@@ -173,8 +174,9 @@ namespace BitFields {
     };
     static_assert(g().s0 + g().s1 + g().b0 + g().b1 == 0xc0 + 0xff + 0xe + 
0xe);
     {
-      // expected-error@+2 {{initialized by a constant expression}}
-      // expected-note@+1 {{read of uninitialized object is not allowed in a 
constant expression}}
+      // expected-error@+3 {{initialized by a constant expression}}
+      // expected-note@+2 {{read of uninitialized object is not allowed in a 
constant expression}}
+      // expected-note@+1 {{temporary created here}}
       constexpr auto _bad = g().b2;
     }
   }
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp 
b/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp
index 1013a771d13b4..7e34c3ff9d755 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp
@@ -61,7 +61,7 @@ constexpr long double foo() {
 static_assert(foo() == ld);
 
 constexpr bool f(bool read_uninit) {
-  bytes b = bit_cast<bytes>(ld);
+  bytes b = bit_cast<bytes>(ld); // both-note {{declared here}}
   unsigned char ld_bytes[10] = {
     0x0,  0x48, 0x9f, 0x49, 0xf0,
     0x3c, 0x20, 0xc9, 0x0,  0x40,
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp 
b/clang/test/AST/ByteCode/builtin-functions.cpp
index 93b6e06490e61..f423ef1c8b301 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -1216,7 +1216,7 @@ namespace shufflevector {
 #if __cplusplus >= 202002L
   constexpr int discarded3() {
     int i = 0;
-    vector4char a;
+    vector4char a; // both-note {{declared here}}
     __builtin_shufflevector((++i, a), a, 0); // both-note {{read of 
uninitialized object}} \
                                              // both-warning {{expression 
result unused}}
     return i;
diff --git a/clang/test/AST/ByteCode/constexpr-nqueens.cpp 
b/clang/test/AST/ByteCode/constexpr-nqueens.cpp
index ed038dbc9b077..63a3e63c3765c 100644
--- a/clang/test/AST/ByteCode/constexpr-nqueens.cpp
+++ b/clang/test/AST/ByteCode/constexpr-nqueens.cpp
@@ -60,7 +60,9 @@ constexpr Board buildBoardRecurse(int N, int Col, const Board 
&B) {
 }
 constexpr Board buildBoard(int N) {
   return buildBoardRecurse(N, 0, Board()); // ref-note {{in call to 
'buildBoardRecurse(8, 0, Board())'}} \
-                                           // expected-note {{in call to 
'buildBoardRecurse(8, 0, Board())'}}
+                                           // expected-note {{in call to 
'buildBoardRecurse(8, 0, Board())'}} \
+                                           // ref-note {{temporary created 
here}} \
+                                           // expected-note {{temporary 
created here}}
 }
 
 constexpr Board q8 = buildBoard(8); // ref-error {{must be initialized by a 
constant expression}} \
diff --git a/clang/test/AST/ByteCode/cxx11.cpp 
b/clang/test/AST/ByteCode/cxx11.cpp
index 668228e2dc166..a4c4be14775b3 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -24,7 +24,8 @@ int array2[recurse2]; // both-warning {{variable length 
arrays in C++}} \
                       // ref-warning {{variable length array folded to 
constant array as an extension}}
 
 constexpr int b = b; // both-error {{must be initialized by a constant 
expression}} \
-                     // both-note {{read of object outside its lifetime is not 
allowed in a constant expression}}
+                     // both-note {{read of object outside its lifetime is not 
allowed in a constant expression}} \
+                     // both-note {{declared here}}
 
 
 [[clang::require_constant_initialization]] int c = c; // both-error {{variable 
does not have a constant initializer}} \
diff --git a/clang/test/AST/ByteCode/cxx17.cpp 
b/clang/test/AST/ByteCode/cxx17.cpp
index 583d9879ad245..166638b0f5211 100644
--- a/clang/test/AST/ByteCode/cxx17.cpp
+++ b/clang/test/AST/ByteCode/cxx17.cpp
@@ -3,7 +3,8 @@
 
 [[clang::require_constant_initialization]] int cc = cc; // both-error 
{{variable does not have a constant initializer}} \
                                                         // both-note 
{{attribute here}} \
-                                                        // both-note {{ead of 
object outside its lifetime}}
+                                                        // both-note {{ead of 
object outside its lifetime}} \
+                                                        // both-note 
{{declared here}}
 
 
 struct F { int a; int b;};
diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index 9800fe01fcaf5..27ba0349d634e 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -57,7 +57,7 @@ constexpr int pointerAssign2() {
 static_assert(pointerAssign2() == 12, "");
 
 constexpr int unInitLocal() {
-  int a;
+  int a; // both-note {{declared here}}
   return a; // both-note {{read of uninitialized object}}
 }
 static_assert(unInitLocal() == 0, ""); // both-error {{not an integral 
constant expression}} \
@@ -71,7 +71,7 @@ constexpr int initializedLocal() {
 static_assert(initializedLocal() == 20);
 
 constexpr int initializedLocal2() {
-  int a[2];
+  int a[2]; // both-note {{declared here}}
   return *a; // both-note {{read of uninitialized object is not allowed in a 
constant expression}}
 }
 static_assert(initializedLocal2() == 20); // both-error {{not an integral 
constant expression}} \
@@ -80,7 +80,7 @@ static_assert(initializedLocal2() == 20); // both-error {{not 
an integral consta
 
 struct Int { int a; };
 constexpr int initializedLocal3() {
-  Int i;
+  Int i; // both-note {{declared here}}
   return i.a; // both-note {{read of uninitialized object is not allowed in a 
constant expression}}
 }
 static_assert(initializedLocal3() == 20); // both-error {{not an integral 
constant expression}} \
@@ -274,7 +274,8 @@ namespace BaseInit {
 
   static_assert(Final{1, 2, 3}.c == 3, ""); // OK
   static_assert(Final{1, 2, 3}.a == 0, ""); // both-error {{not an integral 
constant expression}} \
-                                            // both-note {{read of 
uninitialized object}}
+                                            // both-note {{read of 
uninitialized object}} \
+                                            // both-note {{temporary created 
here}}
 
 
   struct Mixin  {
@@ -294,7 +295,8 @@ namespace BaseInit {
   static_assert(Final2{1, 2, 3}.c == 3, ""); // OK
   static_assert(Final2{1, 2, 3}.b == 2, ""); // OK
   static_assert(Final2{1, 2, 3}.a == 0, ""); // both-error {{not an integral 
constant expression}} \
-                                             // both-note {{read of 
uninitialized object}}
+                                             // both-note {{read of 
uninitialized object}} \
+                                             // both-note {{temporary created 
here}}
 
 
   struct Mixin3  {
@@ -311,7 +313,8 @@ namespace BaseInit {
   static_assert(Final3{1, 2, 3}.c == 3, ""); // OK
   static_assert(Final3{1, 2, 3}.b == 2, ""); // OK
   static_assert(Final3{1, 2, 3}.a == 0, ""); // both-error {{not an integral 
constant expression}} \
-                                             // both-note {{read of 
uninitialized object}}
+                                             // both-note {{read of 
uninitialized object}} \
+                                             // both-note {{temporary created 
here}}
 };
 
 namespace Destructors {
@@ -584,7 +587,7 @@ namespace ImplicitFunction {
   };
 
   constexpr int callMe() {
-   A a;
+   A a; // expected-note {{declared here}}
    A b{12};
 
    /// The operator= call here will fail and the diagnostics should be fine.
@@ -969,7 +972,7 @@ namespace LocalDestroy {
 namespace PseudoDtor {
   constexpr int f1() {
    using T = int;
-   int a = 0;
+   int a = 0; // both-note {{declared here}}
    a.~T();
    return a; // both-note {{read of object outside its lifetime}}
   }
@@ -978,7 +981,7 @@ namespace PseudoDtor {
 
   constexpr int f2() {
    using T = int;
-   int a = 0;
+   int a = 0; // both-note {{declared here}}
    a.~T();
    a = 0; // both-note {{assignment to object outside its lifetime}}
    return a;
diff --git a/clang/test/AST/ByteCode/cxx2a.cpp 
b/clang/test/AST/ByteCode/cxx2a.cpp
index 533173d84792f..78769a4def5b0 100644
--- a/clang/test/AST/ByteCode/cxx2a.cpp
+++ b/clang/test/AST/ByteCode/cxx2a.cpp
@@ -210,7 +210,8 @@ namespace PureVirtual {
 namespace Dtor {
   constexpr bool pseudo(bool read, bool recreate) {
     using T = bool;
-    bool b = false; // both-note {{lifetime has already ended}}
+    bool b = false; // both-note {{lifetime has already ended}} \
+                    // both-note {{declared here}}
     // This evaluates the store to 'b'...
     (b = true).~T();
     // ... and ends the lifetime of the object.
diff --git a/clang/test/AST/ByteCode/lifetimes.cpp 
b/clang/test/AST/ByteCode/lifetimes.cpp
index 96c868209c5b2..e775bed751821 100644
--- a/clang/test/AST/ByteCode/lifetimes.cpp
+++ b/clang/test/AST/ByteCode/lifetimes.cpp
@@ -11,7 +11,7 @@ constexpr int dead1() {
 
   Foo *F2 = nullptr;
   {
-    Foo F{12}; // expected-note {{declared here}}
+    Foo F{12}; // both-note {{declared here}}
     F2 = &F;
   } // Ends lifetime of F.
 
@@ -27,7 +27,7 @@ struct S {
   int t;
   constexpr S() : r(0), t(r) {} // both-error {{reference member 'r' binds to 
a temporary object whose lifetime would be shorter than the lifetime of the 
constructed object}} \
                                 // both-note {{read of object outside its 
lifetime is not allowed in a constant expression}} \
-                                // expected-note {{temporary created here}}
+                                // both-note {{temporary created here}}
 };
 constexpr int k1 = S().t; // both-error {{must be initialized by a constant 
expression}} \
                           // both-note {{in call to}}
@@ -94,7 +94,7 @@ namespace CallScope {
     constexpr int f() const { return 0; }
   };
   constexpr Q *out_of_lifetime(Q q) { return &q; } // both-warning {{address 
of stack}} \
-                                                   // expected-note 
2{{declared here}}
+                                                   // both-note 2{{declared 
here}}
   constexpr int k3 = out_of_lifetime({})->n; // both-error {{must be 
initialized by a constant expression}} \
                                              // expected-note {{read of object 
outside its lifetime}} \
                                              // ref-note {{read of object 
outside its lifetime}}
diff --git a/clang/test/AST/ByteCode/lifetimes26.cpp 
b/clang/test/AST/ByteCode/lifetimes26.cpp
index 8db4ddb1ec51d..7906ef7fca67e 100644
--- a/clang/test/AST/ByteCode/lifetimes26.cpp
+++ b/clang/test/AST/ByteCode/lifetimes26.cpp
@@ -73,8 +73,7 @@ namespace DestroyArrayElem {
                                // both-note {{in call to}}
 
   constexpr int test2() {
-
-    int a[4] = {};
+    int a[4] = {}; // both-note {{declared here}}
     std::destroy_at(&a[1]);
     int r = a[1]; // both-note {{read of object outside its lifetime}}
     std::construct_at(&a[1]);
@@ -85,6 +84,7 @@ namespace DestroyArrayElem {
 
   constexpr int test3() {
     int a[4]; /// Array with no init map.
+    // both-note@-1 {{declared here}}
     std::construct_at(&a[3]);
     return a[3]; // both-note {{read of uninitialized object}}
   }
@@ -92,7 +92,7 @@ namespace DestroyArrayElem {
                                // both-note {{in call to}}
 
   constexpr int test4(bool b) {
-    int a[4];
+    int a[4]; // both-note {{declared here}}
     a[0] = 12;
     std::construct_at(&a[3]);
     return b ? a[0] : a[3]; // both-note {{read of uninitialized object}}
@@ -103,7 +103,7 @@ namespace DestroyArrayElem {
 
 
   constexpr int test5() {
-    int *a = std::allocator<int>{}.allocate(3);
+    int *a = std::allocator<int>{}.allocate(3); // both-note {{heap allocation 
performed here}}
     a[0] = 1; // both-note {{assignment to object outside its lifetime}}
     int b = a[1];
     std::allocator<int>{}.deallocate(a);
diff --git a/clang/test/AST/ByteCode/literals.cpp 
b/clang/test/AST/ByteCode/literals.cpp
index d637eccc448c4..f7eae07c8060a 100644
--- a/clang/test/AST/ByteCode/literals.cpp
+++ b/clang/test/AST/ByteCode/literals.cpp
@@ -541,7 +541,7 @@ namespace IncDec {
   /// current interpreter. But they are stil OK.
   template<typename T, bool Inc, bool Pre>
   constexpr int uninit() {
-    T a;
+    T a; // both-note 10{{declared here}}
     if constexpr (Inc) {
       if (Pre)
         ++a; // ref-note 3{{increment of uninitialized}} \
diff --git a/clang/test/AST/ByteCode/new-delete.cpp 
b/clang/test/AST/ByteCode/new-delete.cpp
index bf892e79a67ac..3eb0d1a13bf49 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -703,7 +703,7 @@ namespace OperatorNewDelete {
   static_assert(zeroAlloc());
 
   constexpr int arrayAlloc() {
-    int *F = std::allocator<int>().allocate(2);
+    int *F = std::allocator<int>().allocate(2); // both-note {{heap allocation 
performed here}}
     F[0] = 10; // both-note {{assignment to object outside its lifetime is not 
allowed in a constant expression}}
     F[1] = 13;
     int Res = F[1] + F[0];
@@ -721,7 +721,7 @@ namespace OperatorNewDelete {
 
   /// FIXME: This is broken in the current interpreter.
   constexpr bool structAlloc() {
-    S *s = std::allocator<S>().allocate(1);
+    S *s = std::allocator<S>().allocate(1); // ref-note {{heap allocation 
performed here}}
 
     s->i = 12; // ref-note {{assignment to object outside its lifetime is not 
allowed in a constant expression}}
 
@@ -734,7 +734,7 @@ namespace OperatorNewDelete {
                                 // ref-note {{in call to}}
 
   constexpr bool structAllocArray() {
-    S *s = std::allocator<S>().allocate(9);
+    S *s = std::allocator<S>().allocate(9); // ref-note {{heap allocation 
performed here}}
 
     s[2].i = 12; // ref-note {{assignment to object outside its lifetime is 
not allowed in a constant expression}}
     bool Res = (s[2].i == 12);
@@ -900,7 +900,7 @@ namespace IncompleteArray {
   };
   constexpr int test1() {
     int n = 5;
-    int* a = new int[n];
+    int* a = new int[n]; // both-note {{heap allocation performed here}}
     int c = a[0]; // both-note {{read of uninitialized object}}
     delete[] a;
     return c;
@@ -1155,6 +1155,7 @@ static_assert(a() == 1, ""); // both-error {{not an 
integral constant expression
 
 
 static_assert(true ? *new int : 4, ""); // both-error {{expression is not an 
integral constant expression}} \
-                                        // both-note {{read of uninitialized 
object is not allowed in a constant expression}}
+                                        // both-note {{read of uninitialized 
object is not allowed in a constant expression}} \
+                                        // both-note {{heap allocation 
performed here}}
 
 #endif
diff --git a/clang/test/AST/ByteCode/placement-new.cpp 
b/clang/test/AST/ByteCode/placement-new.cpp
index 5bad616a0d359..a05a4a18eed61 100644
--- a/clang/test/AST/ByteCode/placement-new.cpp
+++ b/clang/test/AST/ByteCode/placement-new.cpp
@@ -27,7 +27,8 @@ void *operator new(std::size_t, void *p) { return p; }
 void* operator new[] (std::size_t, void* p) {return p;}
 
 constexpr int no_lifetime_start = (*std::allocator<int>().allocate(1) = 1); // 
both-error {{constant expression}} \
-                                                                            // 
both-note {{assignment to object outside its lifetime}}
+                                                                            // 
both-note {{assignment to object outside its lifetime}} \
+                                                                            // 
both-note {{heap allocation performed here}}
 
 consteval auto ok1() {
   bool b;
@@ -119,7 +120,7 @@ static_assert(fail2() == 0); // both-error {{not an 
integral constant expression
                              // both-note {{in call to}}
 
 consteval int indeterminate() {
-    int * indeterminate;
+    int * indeterminate; // both-note {{declared here}}
     new (indeterminate) int(0); // both-note {{read of uninitialized object is 
not allowed in a constant expression}}
     return 0;
 }
@@ -178,7 +179,7 @@ static_assert(blah()); // both-error {{not an integral 
constant expression}} \
 
 
 constexpr int *get_indeterminate() {
-  int *evil;
+  int *evil; // both-note {{declared here}}
   return evil; // both-note {{read of uninitialized object is not allowed in a 
constant expression}}
 }
 
@@ -416,7 +417,7 @@ namespace PlacementNewAfterDelete {
 namespace SubObj {
   constexpr bool construct_after_lifetime_2() {
     struct A { struct B {} b; };
-    A a;
+    A a; // both-note {{declared here}}
     a.~A();
     std::construct_at<A::B>(&a.b); // both-note {{in call}}
     return true;
diff --git a/clang/test/AST/ByteCode/records.cpp 
b/clang/test/AST/ByteCode/records.cpp
index db02a7d23151e..29f4f424d7707 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -605,7 +605,7 @@ namespace Destructors {
 
   struct A { int n; };
   constexpr void double_destroy() {
-    A a;
+    A a; // both-note {{declared here}}
     a.~A();
     a.~A(); // both-note {{destruction of object outside its lifetime}}
   }
diff --git a/clang/test/AST/ByteCode/unions.cpp 
b/clang/test/AST/ByteCode/unions.cpp
index 2123a932fce10..8cf1d414b70b1 100644
--- a/clang/test/AST/ByteCode/unions.cpp
+++ b/clang/test/AST/ByteCode/unions.cpp
@@ -121,7 +121,7 @@ namespace SimpleActivate {
         float x,y;
       } a;
       int b;
-    } Z;
+    } Z; // both-note {{declared here}}
 
     Z.a.y = 10;
 
@@ -410,7 +410,7 @@ namespace UnionInBase {
   static_assert(read_wrong_member_indirect() == 1); // both-error {{not an 
integral constant expression}} \
                                                     // both-note {{in call to}}
   constexpr int read_uninitialized() {
-    B b = {.b = 1};
+    B b = {.b = 1}; // both-note {{declared here}}
     int *p = &b.a.y;
     b.a.x = 1;
     return *p; // both-note {{read of uninitialized object}}
diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c
index 69674d8e8f4b2..16352c3752427 100644
--- a/clang/test/C/C23/n3006.c
+++ b/clang/test/C/C23/n3006.c
@@ -58,7 +58,8 @@ void constexpr_test(void) {
 
 void self_reference_test(void) {
   constexpr int i = i;  // expected-error {{constexpr variable 'i' must be 
initialized by a constant expression}} \
-                           expected-note {{read of object outside its lifetime 
is not allowed in a constant expression}}
+                           expected-note {{read of object outside its lifetime 
is not allowed in a constant expression}} \
+                           expected-note {{declared here}}
   auto j = j;           // expected-error {{variable 'j' declared with deduced 
type 'auto' cannot appear in its own initializer}}
 }
 
@@ -103,7 +104,7 @@ void misc_struct_test(void) {
 
   constexpr struct {
       int b;
-  } b = (struct S { int x; }){ 0 };  // expected-error-re {{initializing 
'const struct (unnamed at {{.*}}n3006.c:104:13)' with an expression of 
incompatible type 'struct S'}}
+  } b = (struct S { int x; }){ 0 };  // expected-error-re {{initializing 
'const struct (unnamed at {{.*}}n3006.c:105:13)' with an expression of 
incompatible type 'struct S'}}
 
   auto z = ({
       int a = 12;
diff --git a/clang/test/CXX/drs/cwg2026.cpp b/clang/test/CXX/drs/cwg2026.cpp
index 23469f999b773..a9d04308c10e8 100644
--- a/clang/test/CXX/drs/cwg2026.cpp
+++ b/clang/test/CXX/drs/cwg2026.cpp
@@ -23,12 +23,14 @@ namespace cwg2026 { // cwg2026: 11
   constexpr int b = b;
   // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a 
constant expression}}
   //   since-cxx11-note@-2 {{read of object outside its lifetime is not 
allowed in a constant expression}}
+  //   since-cxx11-note@-3 {{declared here}}
   [[clang::require_constant_initialization]] int c = c;
   // since-cxx11-error@-1 {{variable does not have a constant initializer}}
   //   since-cxx11-note@-2 {{required by 'require_constant_initialization' 
attribute here}}
   //   cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a 
constant expression}}
   //   cxx11-note@-4 {{declared here}}
   //   since-cxx14-note@-5 {{read of object outside its lifetime is not 
allowed in a constant expression}}
+  //   since-cxx14-note@-6 {{declared here}}
 #endif
 
 #if __cplusplus >= 202002L
@@ -36,6 +38,7 @@ namespace cwg2026 { // cwg2026: 11
   // since-cxx20-error@-1 {{variable does not have a constant initializer}}
   //   since-cxx20-note@-2 {{required by 'constinit' specifier here}}
   //   since-cxx20-note@-3 {{read of object outside its lifetime is not 
allowed in a constant expression}}
+  //   since-cxx20-note@-4 {{declared here}}
 #endif
 
   void f() {
@@ -53,12 +56,14 @@ namespace cwg2026 { // cwg2026: 11
     static constexpr int f = f;
     // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a 
constant expression}}
     //   since-cxx11-note@-2 {{read of object outside its lifetime is not 
allowed in a constant expression}}
+    //   since-cxx11-note@-3 {{declared here}}
     [[clang::require_constant_initialization]] static int g = g;
     // since-cxx11-error@-1 {{variable does not have a constant initializer}}
     //   since-cxx11-note@-2 {{required by 'require_constant_initialization' 
attribute here}}
     //   cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a 
constant expression}}
     //   cxx11-note@-4 {{declared here}}
     //   since-cxx14-note@-5 {{read of object outside its lifetime is not 
allowed in a constant expression}}
+    //   since-cxx14-note@-6 {{declared here}}
 #endif
 
 #if __cplusplus >= 202002L
@@ -66,6 +71,7 @@ namespace cwg2026 { // cwg2026: 11
     // since-cxx20-error@-1 {{variable does not have a constant initializer}}
     //   since-cxx20-note@-2 {{required by 'constinit' specifier here}}
     //   since-cxx20-note@-3 {{read of object outside its lifetime is not 
allowed in a constant expression}}
+    //   since-cxx20-note@-4 {{declared here}}
 #endif
   }
 } // namespace cwg2026
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index 041d56ea3a1db..1b7b273f76b66 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -1124,6 +1124,7 @@ namespace cwg367 { // cwg367: 2.7
   static_assert(__enable_constant_folding(true ? *new int : 4), "");
   // expected-error@-1 {{static assertion expression is not an integral 
constant expression}}
   //   expected-note@-2 {{read of uninitialized object is not allowed in a 
constant expression}}
+  //   expected-note@-3 {{heap allocation performed here}}
   static_assert(__enable_constant_folding(true ? 4 : *new int), "");
 } // namespace cwg367
 
diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp 
b/clang/test/CXX/expr/expr.const/p2-0x.cpp
index 8401d3033eda9..01535786655a2 100644
--- a/clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -62,7 +62,7 @@ namespace NonConstExprReturn {
   constexpr const int *address_of(const int &a) {
     return &a;
   }
-  constexpr const int *return_param(int n) {
+  constexpr const int *return_param(int n) { // expected-note {{declared here}}
     return address_of(n);
   }
   struct S {
diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c
index 0b8de906e1838..19f9033cf924e 100644
--- a/clang/test/Sema/constexpr.c
+++ b/clang/test/Sema/constexpr.c
@@ -426,8 +426,9 @@ void gh173847_test() {
 }
 
 int gh173605(int x) {
-  static constexpr int c = c; // expected-error {{constexpr variable 'c' must 
be initialized by a constant expression}}\
-                              // expected-note {{read of object outside its 
lifetime is not allowed in a constant expression}}
+  static constexpr int c = c; // expected-error {{constexpr variable 'c' must 
be initialized by a constant expression}} \
+                              // expected-note {{read of object outside its 
lifetime is not allowed in a constant expression}} \
+                              // expected-note {{declared here}}
   static int justincase = justincase; // expected-error {{initializer element 
is not a compile-time constant}}
   return x;
 }
diff --git a/clang/test/SemaCXX/builtin-is-within-lifetime.cpp 
b/clang/test/SemaCXX/builtin-is-within-lifetime.cpp
index b47efc9f79630..c7ebce55c5c95 100644
--- a/clang/test/SemaCXX/builtin-is-within-lifetime.cpp
+++ b/clang/test/SemaCXX/builtin-is-within-lifetime.cpp
@@ -111,7 +111,7 @@ static_assert(test_dynamic(true));
 consteval bool test_automatic(int read_dangling) {
   int* p;
   {
-    int x = 0;
+    int x = 0; // expected-note 2{{declared here}}
     p = &x;
     if (!__builtin_is_within_lifetime(p))
       return false;
@@ -124,7 +124,7 @@ consteval bool test_automatic(int read_dangling) {
   if (read_dangling == 2)
     __builtin_is_within_lifetime(p); // expected-note {{read of object outside 
its lifetime is not allowed in a constant expression}}
   {
-    int x[4];
+    int x[4]; // expected-note {{declared here}}
     p = &x[2];
     if (!__builtin_is_within_lifetime(p))
       return false;
@@ -133,7 +133,7 @@ consteval bool test_automatic(int read_dangling) {
     __builtin_is_within_lifetime(p); // expected-note {{read of object outside 
its lifetime is not allowed in a constant expression}}
   std::nullptr_t* q;
   {
-    std::nullptr_t np = nullptr;
+    std::nullptr_t np = nullptr; // expected-note {{declared here}}
     q = &np;
     if (!__builtin_is_within_lifetime(q))
       return false;
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 91c4ff1cb520d..47a064c4026b4 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -232,7 +232,7 @@ namespace ParameterScopes {
 
   const int k = 42;
   constexpr const int &ObscureTheTruth(const int &a) { return a; }
-  constexpr const int &MaybeReturnJunk(bool b, const int a) {
+  constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 
2{{declared here}}
     return ObscureTheTruth(b ? a : k);
   }
   static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok
@@ -694,7 +694,8 @@ static_assert(selfref[1][0][1] == 3, "");
 static_assert(selfref[1][1][0] == 0, "");
 static_assert(selfref[1][1][1] == 0, "");
 
-constexpr int badselfref[2][2][2] = { // expected-error {{constant expression}}
+constexpr int badselfref[2][2][2] = { // expected-error {{constant 
expression}} \
+                                      // expected-note {{declared here}}
   badselfref[1][0][0] // expected-note {{outside its lifetime}}
 };
 
@@ -1378,7 +1379,7 @@ namespace ExternConstexpr {
     constexpr int k; // expected-error {{constexpr variable 'k' must be 
initialized by a constant expression}}
   }
 
-  extern const int q;
+  extern const int q; // expected-note {{declared here}}
   constexpr int g() { return q; } // expected-note {{outside its lifetime}}
   constexpr int q = g(); // expected-error {{constant expression}} 
expected-note {{in call}}
 
@@ -1386,7 +1387,7 @@ namespace ExternConstexpr {
   constexpr int h() { return r; } // cxx11_20-error {{never produces a 
constant}} cxx11_20-note {{read of non-const}}
 
   struct S { int n; };
-  extern const S s;
+  extern const S s; // expected-note {{declared here}}
   constexpr int x() { return s.n; } // expected-note {{outside its lifetime}}
   constexpr S s = {x()}; // expected-error {{constant expression}} 
expected-note {{in call}}
 }
@@ -2014,7 +2015,9 @@ namespace Lifetime {
   void f() {
     constexpr int &n = n; // expected-error {{constant expression}} cxx23-note 
{{reference to 'n' is not a constant expression}} cxx23-note {{address of 
non-static constexpr variable 'n' may differ}} expected-warning {{not yet bound 
to a value}}
                           // cxx11_20-note@-1 {{use of reference outside its 
lifetime is not allowed in a constant expression}}
-    constexpr int m = m; // expected-error {{constant expression}} 
expected-note {{read of object outside its lifetime}}
+    constexpr int m = m; // expected-error {{constant expression}} \
+                         // expected-note {{read of object outside its 
lifetime}} \
+                         // expected-note {{declared here}}
   }
 
   constexpr int &get(int &&n) { return n; }
@@ -2024,8 +2027,10 @@ namespace Lifetime {
     int &&r;
     int &s;
     int t;
-    constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // cxx11_20-note {{read 
of object outside its lifetime}}
-    constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {} // cxx11_20-note 
{{read of object outside its lifetime}}
+    constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // cxx11_20-note {{read 
of object outside its lifetime}} \
+                                                     // cxx11_20-note 
{{temporary created here}}
+    constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {} // cxx11_20-note 
{{read of object outside its lifetime}} \
+                                                        // cxx11_20-note 
{{temporary created here}}
   };
   constexpr int k1 = S().t; // expected-error {{constant expression}} 
cxx11_20-note {{in call}}
   constexpr int k2 = S(0).t; // expected-error {{constant expression}} 
cxx11_20-note {{in call}}
@@ -2034,7 +2039,8 @@ namespace Lifetime {
     int n = 0;
     constexpr int f() const { return 0; }
   };
-  constexpr Q *out_of_lifetime(Q q) { return &q; } // expected-warning 
{{address of stack}}
+  constexpr Q *out_of_lifetime(Q q) { return &q; } // expected-warning 
{{address of stack}} \
+                                                   // expected-note 
2{{declared here}}
   constexpr int k3 = out_of_lifetime({})->n; // expected-error {{constant 
expression}} expected-note {{read of object outside its lifetime}}
   constexpr int k4 = out_of_lifetime({})->f(); // expected-error {{constant 
expression}} expected-note {{member call on object outside its lifetime}}
 
@@ -2070,9 +2076,14 @@ namespace Lifetime {
     int a = b.f(); // expected-warning {{uninitialized}} expected-note 
2{{member call on object outside its lifetime}}
     Inner b;
   };
-  constexpr R r; // expected-error {{constant expression}} expected-note {{in 
call}} expected-note {{implicit default constructor for 'Lifetime::R' first 
required here}}
+  constexpr R r; // expected-error {{constant expression}} \
+                 // expected-note {{in call}} \
+                 // expected-note {{implicit default constructor for 
'Lifetime::R' first required here}} \
+                 // expected-note {{declared here}}
   void rf() {
-    constexpr R r; // expected-error {{constant expression}} expected-note 
{{in call}}
+    constexpr R r; // expected-error {{constant expression}} \
+                   // expected-note {{in call}} \
+                   // expected-note {{declared here}}
   }
 }
 
diff --git a/clang/test/SemaCXX/constant-expression-cxx14.cpp 
b/clang/test/SemaCXX/constant-expression-cxx14.cpp
index a917837410ee5..9c0e87cac54cf 100644
--- a/clang/test/SemaCXX/constant-expression-cxx14.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx14.cpp
@@ -842,7 +842,8 @@ namespace StmtExpr {
   static_assert(f(1) == 1, ""); // expected-error {{constant expression}} 
expected-note {{in call}}
 
   constexpr int g() {
-    return ({ int n; n; }); // expected-note {{read of uninitialized object}}
+    return ({ int n; n; }); // expected-note {{read of uninitialized object}} \
+                            // expected-note {{declared here}}
   }
   static_assert(g() == 0, ""); // expected-error {{constant expression}} 
expected-note {{in call}}
 
@@ -881,7 +882,7 @@ namespace Lifetime {
   constexpr int &get(int &&r) { return r; }
   // cxx23-error@-1 {{non-const lvalue reference to type 'int' cannot bind to 
a temporary of type 'int'}}
   constexpr int f() {
-    int &r = get(123);
+    int &r = get(123); // cxx14_20-note {{temporary created here}}
     return r;
     // cxx14_20-note@-1 {{read of object outside its lifetime}}
   }
@@ -890,7 +891,7 @@ namespace Lifetime {
   constexpr int g() {
     int *p = 0;
     {
-      int n = 0;
+      int n = 0; // expected-note {{declared here}}
       p = &n;
       n = 42;
     }
@@ -903,9 +904,9 @@ namespace Lifetime {
     int *p[4] = {};
     int &&r = 1;
     p[0] = &r;
-    while (int a = 1) {
+    while (int a = 1) { // expected-note {{declared here}}
       p[1] = &a;
-      for (int b = 1; int c = 1; ) {
+      for (int b = 1; int c = 1; ) { // expected-note 2{{declared here}}
         p[2] = &b, p[3] = &c;
         break;
       }
@@ -923,7 +924,7 @@ namespace Lifetime {
     int *p = 0;
     for (int i = 0; i != 2; ++i) {
       int *q = p;
-      int n = 0;
+      int n = 0; // expected-note {{declared here}}
       p = &n;
       if (i)
         // This modifies the 'n' from the previous iteration of the loop 
outside
@@ -955,7 +956,7 @@ namespace PR17615 {
   struct A {
     int &&r;
     constexpr A(int &&r) : r(static_cast<int &&>(r)) {}
-    constexpr A() : A(0) {
+    constexpr A() : A(0) { // expected-note {{temporary created here}}
       (void)+r; // expected-note {{outside its lifetime}}
     }
   };
@@ -1124,7 +1125,9 @@ struct A {
   };
   constexpr A() {}
 };
-static_assert(A().x == 3, ""); // cxx14-error{{not an integral constant 
expression}} cxx14-note{{in call to 'A()'}}
+static_assert(A().x == 3, ""); // cxx14-error{{not an integral constant 
expression}} \
+                               // cxx14-note{{in call to 'A()'}} \
+                               // cxx14-note {{temporary created here}}
 
 // Reference another indirect field, with different 'this'.
 struct B {
@@ -1239,7 +1242,9 @@ namespace ObjectsUnderConstruction {
   static_assert(aggr2.x == 1 && aggr2.y == 1, "");
 
   // The lifetime of 'n' begins at the initialization, not before.
-  constexpr int n = ++const_cast<int&>(n); // expected-error {{constant 
expression}} expected-note {{increment of object outside its lifetime}}
+  constexpr int n = ++const_cast<int&>(n); // expected-error {{constant 
expression}} \
+                                           // expected-note {{increment of 
object outside its lifetime}} \
+                                           // expected-note {{declared here}}
 }
 
 namespace PR39728 {
diff --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp 
b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
index fb60b5300c362..396a8df21a3e3 100644
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -372,7 +372,7 @@ namespace Union {
     return *p; // expected-note {{read of member 'a' of union with active 
member 'b'}}
   }
   constexpr int read_uninitialized() {
-    B b = {.b = 1};
+    B b = {.b = 1}; // expected-note {{declared here}}
     int *p = &b.a.y;
     b.a.x = 1;
     return *p; // expected-note {{read of uninitialized object}}
@@ -542,7 +542,7 @@ namespace TwosComplementShifts {
 
 namespace Uninit {
   constexpr int f(bool init) {
-    int a;
+    int a; // expected-note {{declared here}}
     if (init)
       a = 1;
     return a; // expected-note {{read of uninitialized object}}
@@ -576,20 +576,26 @@ namespace Uninit {
   };
   // FIXME: This is working around clang not implementing DR2026. With that
   // fixed, we should be able to test this without the injected copy.
-  constexpr Y copy(Y y) { return y; } // expected-note {{in call to 'Y(y)'}} 
expected-note {{subobject 'n' is not initialized}}
+  constexpr Y copy(Y y) { return y; } // expected-note {{in call to 'Y(y)'}} \
+                                      // expected-note {{subobject 'n' is not 
initialized}} \
+                                      // expected-note {{declared here}}
   constexpr Y y1 = copy(Y());
   static_assert(y1.z1.n == 1 && y1.z2.n == 2 && y1.z3.n == 3);
 
   constexpr Y y2 = copy(Y(0)); // expected-error {{constant expression}} 
expected-note {{in call}}
 
   static_assert(Y(0,0).z2.n == 0);
-  static_assert(Y(0,0).z1.n == 0); // expected-error {{constant expression}} 
expected-note {{read of uninitialized object}}
-  static_assert(Y(0,0).z3.n == 0); // expected-error {{constant expression}} 
expected-note {{read of uninitialized object}}
+  static_assert(Y(0,0).z1.n == 0); // expected-error {{constant expression}} \
+                                   // expected-note {{read of uninitialized 
object}} \
+                                   // expected-note {{temporary created here}}
+  static_assert(Y(0,0).z3.n == 0); // expected-error {{constant expression}} \
+                                   // expected-note {{read of uninitialized 
object}} \
+                                   // expected-note {{temporary created here}}
 
   static_assert(copy(Y(0,0)).z2.n == 0); // expected-error {{constant 
expression}} expected-note {{in call}}
 
   constexpr unsigned char not_even_unsigned_char() {
-    unsigned char c;
+    unsigned char c; // expected-note {{declared here}}
     return c; // expected-note {{read of uninitialized object}}
   }
   constexpr unsigned char x = not_even_unsigned_char(); // expected-error 
{{constant expression}} expected-note {{in call}}
@@ -1086,7 +1092,8 @@ namespace dtor_call {
 
   constexpr bool pseudo(bool read, bool recreate) {
     using T = bool;
-    bool b = false; // expected-note {{lifetime has already ended}}
+    bool b = false; // expected-note {{lifetime has already ended}} \
+                    // expected-note {{declared here}}
     // This evaluates the store to 'b'...
     (b = true).~T();
     // ... and ends the lifetime of the object.
@@ -1102,14 +1109,14 @@ namespace dtor_call {
   static_assert(pseudo(false, true));
 
   constexpr void use_after_destroy() {
-    A a;
+    A a; // expected-note {{declared here}}
     a.~A();
     A b = a; // expected-note {{in call}} expected-note {{read of object 
outside its lifetime}}
   }
   static_assert((use_after_destroy(), true)); // expected-error {{}} 
expected-note {{in call}}
 
   constexpr void double_destroy() {
-    A a;
+    A a; // expected-note {{declared here}}
     a.~A();
     a.~A(); // expected-note {{destruction of object outside its lifetime}}
   }
@@ -1176,7 +1183,7 @@ namespace dtor_call {
 
   constexpr void use_after_virt_destroy() {
     char buff[4] = {};
-    VU vu;
+    VU vu; // expected-note {{declared here}}
     vu.z.p = buff;
     ((Y&)vu.z).~Y();
     ((Z&)vu.z).z = 1; // expected-note {{assignment to object outside its 
lifetime}}
@@ -1186,7 +1193,7 @@ namespace dtor_call {
   constexpr void destroy_after_lifetime() {
     A *p;
     {
-      A a;
+      A a; // expected-note {{declared here}}
       p = &a;
     }
     p->~A(); // expected-note {{destruction of object outside its lifetime}}
diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp 
b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
index 0a7668b1ed1fe..839de82744379 100644
--- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
@@ -278,7 +278,7 @@ constexpr int test_indeterminate(bool read_indet) {
   };
 
   pad p{1, 2};
-  no_pad np = bit_cast<no_pad>(p);
+  no_pad np = bit_cast<no_pad>(p); // expected-note {{declared here}}
 
   int tmp = np.a + np.b;
 
@@ -343,7 +343,7 @@ constexpr B one() {
 constexpr char good_one = one().x[0] + one().x[2] + one().x[3];
 // expected-error@+2 {{constexpr variable 'bad_one' must be initialized by a 
constant expression}}
 // expected-note@+1 {{read of uninitialized object is not allowed in a 
constant expression}}
-constexpr char bad_one = one().x[1];
+constexpr char bad_one = one().x[1]; // expected-note {{temporary created 
here}}
 
 constexpr A two() {
   B b = one(); // b.x[1] is indeterminate.
@@ -433,7 +433,7 @@ static_assert(round_trip<bytes>(ld), "");
 static_assert(round_trip<long double>(10.0L));
 
 constexpr bool f(bool read_uninit) {
-  bytes b = bit_cast<bytes>(ld);
+  bytes b = bit_cast<bytes>(ld); // expected-note {{declared here}}
   unsigned char ld_bytes[10] = {
     0x0,  0x48, 0x9f, 0x49, 0xf0,
     0x3c, 0x20, 0xc9, 0x0,  0x40,
diff --git a/clang/test/SemaCXX/constexpr-printing.cpp 
b/clang/test/SemaCXX/constexpr-printing.cpp
index 08c80a0bb7fdb..b5aa050aea25f 100644
--- a/clang/test/SemaCXX/constexpr-printing.cpp
+++ b/clang/test/SemaCXX/constexpr-printing.cpp
@@ -12,7 +12,9 @@ struct S {
 constexpr int extract(const S &s) { return s.n; } // expected-note {{read of 
object outside its lifetime is not allowed in a constant expression}}
 
 void f() {
-  constexpr S s1; // expected-error {{constant expression}} expected-note {{in 
call to 'S()'}}
+  constexpr S s1; // expected-error {{constant expression}} \
+                  // expected-note {{in call to 'S()'}} \
+                  // expected-note {{declared here}}
   constexpr S s2(10);
 }
 
diff --git a/clang/test/SemaCXX/constexpr-value-init.cpp 
b/clang/test/SemaCXX/constexpr-value-init.cpp
index 18fa9cf0736a6..bd1c254dd200a 100644
--- a/clang/test/SemaCXX/constexpr-value-init.cpp
+++ b/clang/test/SemaCXX/constexpr-value-init.cpp
@@ -10,13 +10,21 @@ struct B { // expected-note {{in call to 'A()'}}
   A a;
 };
 
-constexpr A a1; // expected-error {{constant expression}} expected-note {{in 
call to 'A()'}}
-constexpr A a2 = A(); // expected-error {{constant expression}} expected-note 
{{in call to 'A()'}}
+constexpr A a1; // expected-error {{constant expression}} \
+                // expected-note {{in call to 'A()'}} \
+                // expected-note {{declared here}}
+constexpr A a2 = A(); // expected-error {{constant expression}} \
+                      // expected-note {{in call to 'A()'}} \
+                      // expected-note {{declared here}}
 void f() {
-  constexpr A a; // expected-error {{constant expression}} expected-note {{in 
call to 'A()'}}
+  constexpr A a; // expected-error {{constant expression}} \
+                 // expected-note {{in call to 'A()'}} \
+                 // expected-note {{declared here}}
 }
 
-constexpr B b1; // expected-error {{constant expression}} expected-note {{in 
call to 'B()'}}
+constexpr B b1; // expected-error {{constant expression}} \
+                // expected-note {{in call to 'B()'}} \
+                // expected-note {{declared here}}
 constexpr B b2 = B(); // ok
 static_assert(b2.a.a == 1, "");
 static_assert(b2.a.b == 2, "");
@@ -41,7 +49,9 @@ constexpr int n = Z<V>().c; // expected-error {{constant 
expression}} expected-n
 struct E { // expected-note {{in call to 'A()'}}
   A a[2];
 };
-constexpr E e1; // expected-error {{constant expression}} expected-note {{in 
call to 'E()'}}
+constexpr E e1; // expected-error {{constant expression}} \
+                // expected-note {{in call to 'E()'}} \
+                // expected-note {{declared here}}
 constexpr E e2 = E();
 static_assert(e2.a[0].a == 1, "");
 static_assert(e2.a[0].b == 2, "");
diff --git a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp 
b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp
index 25cd2c9538a90..3088923c009ae 100644
--- a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp
+++ b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp
@@ -89,7 +89,9 @@ constexpr int *escape = std::allocator<int>().allocate(3); // 
expected-error {{c
                                                            // expected-note 
{{heap allocation performed here}}
 constexpr int leak = (std::allocator<int>().allocate(3), 0); // expected-error 
{{constant expression}} \
                                                              // expected-note 
{{not deallocated}}
-constexpr int no_lifetime_start = (*std::allocator<int>().allocate(1) = 1); // 
expected-error {{constant expression}} expected-note {{assignment to object 
outside its lifetime}}
+constexpr int no_lifetime_start = (*std::allocator<int>().allocate(1) = 1); // 
expected-error {{constant expression}} \
+                                                                            // 
expected-note {{assignment to object outside its lifetime}} \
+                                                                            // 
expected-note {{heap allocation performed here}}
 constexpr int no_deallocate_nullptr = 
(std::allocator<int>().deallocate(nullptr), 1); // expected-error {{constant 
expression}} expected-note {{in call}}
 // expected-note@#dealloc {{'std::allocator<...>::deallocate' used to delete a 
null pointer}}
 constexpr int no_deallocate_nonalloc = 
(std::allocator<int>().deallocate((int*)&no_deallocate_nonalloc), 1); // 
expected-error {{constant expression}} expected-note {{in call}}
@@ -182,7 +184,7 @@ static_assert(construct_after_lifetime()); // 
expected-error {{}} expected-note
 
 constexpr bool construct_after_lifetime_2() {
   struct A { struct B {} b; };
-  A a;
+  A a; // expected-note {{declared here}}
   a.~A();
   std::construct_at<A::B>(&a.b); // expected-note {{in call}}
   // expected-note@#new {{construction of subobject of object outside its 
lifetime is not allowed in a constant expression}}
diff --git a/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp 
b/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp
index 4cf0e9ffe1d64..7034a45231281 100644
--- a/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp
+++ b/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp
@@ -26,7 +26,7 @@ consteval int conversion() {
 }
 
 consteval int indeterminate() {
-    int * indeterminate;
+    int * indeterminate; // expected-note {{declared here}}
     new (indeterminate) int(0);
     // expected-note@-1 {{read of uninitialized object is not allowed in a 
constant expression}}
     return 0;
@@ -105,7 +105,7 @@ static_assert(blah()); // expected-error {{not an integral 
constant expression}}
                        // expected-note {{in call to 'blah()'}}
 
 constexpr int *get_indeterminate() {
-  int *evil;
+  int *evil; // expected-note {{declared here}}
   return evil; // expected-note {{read of uninitialized object is not allowed 
in a constant expression}}
 }
 
diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp 
b/clang/test/SemaCXX/static-assert-cxx26.cpp
index b2ebd2abb785e..5dbe2c37307bd 100644
--- a/clang/test/SemaCXX/static-assert-cxx26.cpp
+++ b/clang/test/SemaCXX/static-assert-cxx26.cpp
@@ -271,7 +271,7 @@ struct InvalidPtr {
         return 42;
     }
     consteval const char *data() {
-    const char *ptr; // Garbage
+    const char *ptr; // expected-note {{declared here}}
     return ptr; // expected-note {{read of uninitialized object is not allowed 
in a constant expression}}
     }
 };

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

Reply via email to