[clang] [clang][NFC] Refactor expected directives in C++ DRs 2000-2799 (PR #74921)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 9 00:16:29 PST 2023


https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/74921

This patch continues the work started with ea5b1ef016d020c37f903d6c7d4f623be975dab8. See that commit and its corresponding PR for details.

>From 436502773b1720e0511f4371c7a04079e7d38215 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 9 Dec 2023 11:12:19 +0300
Subject: [PATCH] [clang][NFC] Refactor expected directives in C++ DRs
 2000-2799

This patch continues the work started with ea5b1ef016d020c37f903d6c7d4f623be975dab8. See that commit and its corresponding PR for details.
---
 clang/test/CXX/drs/dr20xx.cpp | 219 +++++++++++++++++++++-------------
 clang/test/CXX/drs/dr21xx.cpp | 141 ++++++++++++++--------
 clang/test/CXX/drs/dr22xx.cpp |  37 +++---
 clang/test/CXX/drs/dr2354.cpp |  10 --
 clang/test/CXX/drs/dr23xx.cpp |  57 ++++++---
 clang/test/CXX/drs/dr2406.cpp |  30 -----
 clang/test/CXX/drs/dr24xx.cpp |  51 +++++++-
 clang/test/CXX/drs/dr25xx.cpp | 106 ++++++++--------
 clang/test/CXX/drs/dr26xx.cpp | 121 ++++++++++++-------
 clang/test/CXX/drs/dr27xx.cpp |  25 +++-
 10 files changed, 499 insertions(+), 298 deletions(-)
 delete mode 100644 clang/test/CXX/drs/dr2354.cpp
 delete mode 100644 clang/test/CXX/drs/dr2406.cpp

diff --git a/clang/test/CXX/drs/dr20xx.cpp b/clang/test/CXX/drs/dr20xx.cpp
index 4f81b0b413d4bd..60ee7684440f54 100644
--- a/clang/test/CXX/drs/dr20xx.cpp
+++ b/clang/test/CXX/drs/dr20xx.cpp
@@ -1,13 +1,14 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors \
-// RUN:            -Wno-variadic-macros -Wno-c11-extensions
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-
-#if __cplusplus < 201103L
-#define static_assert(...) _Static_assert(__VA_ARGS__)
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus == 199711L
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error at -1 {{variadic macros are a C99 feature}}
 #endif
 
 namespace dr2007 { // dr2007: 3.4
@@ -15,8 +16,12 @@ template<typename T> struct A { typename T::error e; };
 template<typename T> struct B { };
 B<A<void> > b1;
 B<A<void> > b2 = b1;
-int a = b2[0]; // expected-error {{does not provide a subscript operator}}
-int b = __builtin_addressof(b2)->foo; // expected-error {{no member}}
+int a = b2[0];
+// cxx98-error at -1 {{type 'B<A<void> >' does not provide a subscript operator}}
+// since-cxx11-error at -2 {{type 'B<A<void>>' does not provide a subscript operator}}
+int b = __builtin_addressof(b2)->foo;
+// cxx98-error at -1 {{no member named 'foo' in 'dr2007::B<dr2007::A<void> >'}}
+// since-cxx11-error at -2 {{no member named 'foo' in 'dr2007::B<dr2007::A<void>>'}}
 }
 
 // dr2009: na
@@ -24,45 +29,69 @@ int b = __builtin_addressof(b2)->foo; // expected-error {{no member}}
 namespace dr2026 { // dr2026: 11
   template<int> struct X {};
 
-  const int a = a + 1; // expected-warning {{uninitialized}} expected-note {{here}} expected-note 0-1{{outside its lifetime}}
-  X<a> xa; // expected-error {{constant expression}} expected-note {{initializer of 'a'}}
+  const int a = a + 1; // #dr2026-a
+  // expected-warning at -1 {{variable 'a' is uninitialized when used within its own initialization}}
+  X<a> xa; // #dr2026-xa
+  // cxx98-error at -1 {{non-type template argument of type 'int' is not an integral constant expression}}
+  //   cxx98-note at -2 {{initializer of 'a' is not a constant expression}}
+  //   cxx98-note@#dr2026-a {{declared here}}
+  // since-cxx11-error@#dr2026-xa {{non-type template argument is not a constant expression}}
+  //   since-cxx11-note@#dr2026-xa {{initializer of 'a' is not a constant expression}}
+  //   since-cxx11-note@#dr2026-a {{declared here}}
 
 #if __cplusplus >= 201103L
-  constexpr int b = b; // expected-error {{constant expression}} expected-note {{outside its lifetime}}
-  [[clang::require_constant_initialization]] int c = c; // expected-error {{constant initializer}} expected-note {{attribute}}
-#if __cplusplus == 201103L
-  // expected-note at -2 {{read of non-const variable}} expected-note at -2 {{declared here}}
-#else
-  // expected-note at -4 {{outside its lifetime}}
-#endif
+  constexpr int b = b;
+  // since-cxx11-error at -1 {{constexpr variable 'b' must be initialized by a constant expression}}
+  //   since-cxx11-note at -2 {{read of object outside its lifetime is not allowed in a constant expression}}
+  [[clang::require_constant_initialization]] int c = c;
+  // since-cxx11-error at -1 {{variable does not have a constant initializer}}
+  //   since-cxx11-note at -2 {{required by 'require_constant_initialization' attribute here}}
+  //   cxx11-note at -3 {{read of non-const variable 'c' is not allowed in a constant expression}}
+  //   cxx11-note at -4 {{declared here}}
+  //   since-cxx14-note at -5 {{read of object outside its lifetime is not allowed in a constant expression}}
 #endif
 
-#if __cplusplus > 201703L
-  constinit int d = d; // expected-error {{constant initializer}} expected-note {{outside its lifetime}} expected-note {{'constinit'}}
+#if __cplusplus >= 202002L
+  constinit int d = d;
+  // since-cxx20-error at -1 {{variable does not have a constant initializer}}
+  //   since-cxx20-note at -2 {{required by 'constinit' specifier here}}
+  //   since-cxx20-note at -3 {{read of object outside its lifetime is not allowed in a constant expression}}
 #endif
 
   void f() {
-    static const int e = e + 1; // expected-warning {{suspicious}} expected-note {{here}} expected-note 0-1{{outside its lifetime}}
-    X<e> xe; // expected-error {{constant expression}} expected-note {{initializer of 'e'}}
+    static const int e = e + 1; // #dr2026-e
+    // expected-warning at -1 {{static variable 'e' is suspiciously used within its own initialization}}
+    X<e> xe; // #dr2026-xe
+    // cxx98-error at -1 {{non-type template argument of type 'int' is not an integral constant expression}}
+    //   cxx98-note at -2 {{initializer of 'e' is not a constant expression}}
+    //   cxx98-note@#dr2026-e {{declared here}}
+    // since-cxx11-error@#dr2026-xe {{non-type template argument is not a constant expression}}
+    //   since-cxx11-note@#dr2026-xe {{initializer of 'e' is not a constant expression}}
+    //   since-cxx11-note@#dr2026-e {{declared here}}
 
 #if __cplusplus >= 201103L
-    static constexpr int f = f; // expected-error {{constant expression}} expected-note {{outside its lifetime}}
-    [[clang::require_constant_initialization]] static int g = g; // expected-error {{constant initializer}} expected-note {{attribute}}
-#if __cplusplus == 201103L
-    // expected-note at -2 {{read of non-const variable}} expected-note at -2 {{declared here}}
-#else
-    // expected-note at -4 {{outside its lifetime}}
-#endif
+    static constexpr int f = f;
+    // since-cxx11-error at -1 {{constexpr variable 'f' must be initialized by a constant expression}}
+    //   since-cxx11-note at -2 {{read of object outside its lifetime is not allowed in a constant expression}}
+    [[clang::require_constant_initialization]] static int g = g;
+    // since-cxx11-error at -1 {{variable does not have a constant initializer}}
+    //   since-cxx11-note at -2 {{required by 'require_constant_initialization' attribute here}}
+    //   cxx11-note at -3 {{read of non-const variable 'g' is not allowed in a constant expression}}
+    //   cxx11-note at -4 {{declared here}}
+    //   since-cxx14-note at -5 {{read of object outside its lifetime is not allowed in a constant expression}}
 #endif
 
-#if __cplusplus > 201703L
-    static constinit int h = h; // expected-error {{constant initializer}} expected-note {{outside its lifetime}} expected-note {{'constinit'}}
+#if __cplusplus >= 202002L
+    static constinit int h = h;
+    // since-cxx20-error at -1 {{variable does not have a constant initializer}}
+    //   since-cxx20-note at -2 {{required by 'constinit' specifier here}}
+    //   since-cxx20-note at -3 {{read of object outside its lifetime is not allowed in a constant expression}}
 #endif
   }
 }
 
 namespace dr2049 { // dr2049: 18 drafting
-#if __cplusplus > 202002L
+#if __cplusplus >= 202302L
 template <int* x = {}> struct X {};
 X<> a;
 X<nullptr> b;
@@ -120,8 +149,8 @@ namespace dr2076 { // dr2076: 13
     operator string_view() const;
   };
 
-  void foo(const string &); // expected-note {{cannot convert initializer list}}
-  void bar(string_view); // expected-note 2{{cannot convert initializer list}}
+  void foo(const string &); // #dr2076-foo 
+  void bar(string_view); // #dr2076-bar
 
   void func(const string &arg) {
     // An argument in one set of braces is subject to user-defined conversions;
@@ -130,11 +159,17 @@ namespace dr2076 { // dr2076: 13
     foo(arg);
     foo({arg});
     foo({{arg}});
-    foo({{{arg}}}); // expected-error {{no matching function}}
+    foo({{{arg}}});
+    // since-cxx11-error at -1 {{no matching function}}
+    //   since-cxx11-note@#dr2076-foo  {{cannot convert initializer list}}
     bar(arg);
     bar({arg});
-    bar({{arg}}); // expected-error {{no matching function}}
-    bar({{{arg}}}); // expected-error {{no matching function}}
+    bar({{arg}});
+    // since-cxx11-error at -1 {{no matching function}}
+    //   since-cxx11-note@#dr2076-bar {{cannot convert initializer list}}
+    bar({{{arg}}});
+    // since-cxx11-error at -1 {{no matching function}}
+    //   since-cxx11-note@#dr2076-bar {{cannot convert initializer list}}
   }
 #endif
 }
@@ -172,18 +207,20 @@ namespace dr2083 { // dr2083: partial
   // treatment in C++11 onwards. We continue to apply that even after DR2083.
   void ref_to_non_const() {
     int c;
-    const int &ra = a; // expected-note 0-1{{here}}
-    int &rb = b; // expected-note 0-1{{here}}
-    int &rc = c; // expected-note {{here}}
+    const int &ra = a; // #dr2083-ra
+    int &rb = b; // #dr2083-rb
+    int &rc = c; // #dr2083-rc
     struct A {
       int f() {
         int a = ra;
+        // cxx98-error at -1 {{reference to local variable 'ra' declared in enclosing function 'dr2083::ref_to_non_const'}}
+        //   cxx98-note@#dr2083-ra {{'ra' declared here}}
         int b = rb;
-#if __cplusplus < 201103L
-        // expected-error at -3 {{in enclosing function}}
-        // expected-error at -3 {{in enclosing function}}
-#endif
-        int c = rc; // expected-error {{in enclosing function}}
+        // cxx98-error at -1 {{reference to local variable 'rb' declared in enclosing function 'dr2083::ref_to_non_const'}}
+        //   cxx98-note@#dr2083-rb {{'rb' declared here}}
+        int c = rc;
+        // expected-error at -1 {{reference to local variable 'rc' declared in enclosing function 'dr2083::ref_to_non_const'}}
+        //   expected-note@#dr2083-rc {{'rc' declared here}}
         return a + b + c;
       }
     };
@@ -207,18 +244,24 @@ namespace dr2083 { // dr2083: partial
     constexpr NoMut1 nm1 = {1, 2};
     constexpr NoMut2 nm2 = {1, 2};
     constexpr NoMut3 nm3 = {1, 2};
-    constexpr Mut1 m1 = {1, 2}; // expected-note {{declared here}}
-    constexpr Mut2 m2 = {1, 2}; // expected-note {{declared here}}
-    constexpr Mut3 m3 = {1, 2}; // expected-note {{declared here}}
+    constexpr Mut1 m1 = {1, 2}; // #dr2083-m1
+    constexpr Mut2 m2 = {1, 2}; // #dr2083-m2
+    constexpr Mut3 m3 = {1, 2}; // #dr2083-m3
     struct A {
       void f() {
         static_assert(nm1.a == 1, "");
         static_assert(nm2.m.a == 1, "");
         static_assert(nm3.a == 1, "");
         // Can't even access a non-mutable member of a variable containing mutable fields.
-        static_assert(m1.a == 1, ""); // expected-error {{enclosing function}}
-        static_assert(m2.m.a == 1, ""); // expected-error {{enclosing function}}
-        static_assert(m3.a == 1, ""); // expected-error {{enclosing function}}
+        static_assert(m1.a == 1, "");
+        // since-cxx11-error at -1 {{reference to local variable 'm1' declared in enclosing function 'dr2083::mutable_subobjects'}}
+        //   since-cxx11-note@#dr2083-m1 {{'m1' declared here}}
+        static_assert(m2.m.a == 1, "");
+        // since-cxx11-error at -1 {{reference to local variable 'm2' declared in enclosing function 'dr2083::mutable_subobjects'}}
+        //   since-cxx11-note@#dr2083-m2 {{'m2' declared here}}
+        static_assert(m3.a == 1, "");
+        // since-cxx11-error at -1 {{reference to local variable 'm3' declared in enclosing function 'dr2083::mutable_subobjects'}}
+        //   since-cxx11-note@#dr2083-m3 {{'m3' declared here}}
       }
     };
   }
@@ -231,14 +274,16 @@ namespace dr2083 { // dr2083: partial
 #if __cplusplus >= 201103L
     constexpr
 #endif
-      A a = {}; // expected-note {{here}}
+      A a = {}; // #dr2083-a
     struct B {
       void f() {
         ellipsis(n);
         // Even though this is technically modelled as an lvalue-to-rvalue
         // conversion, it calls a constructor and binds 'a' to a reference, so
         // it results in an odr-use.
-        ellipsis(a); // expected-error {{enclosing function}}
+        ellipsis(a);
+        // expected-error at -1 {{reference to local variable 'a' declared in enclosing function 'dr2083::ellipsis'}}
+        //   expected-note@#dr2083-a {{'a' declared here}}
       }
     };
   }
@@ -246,7 +291,7 @@ namespace dr2083 { // dr2083: partial
 #if __cplusplus >= 201103L
   void volatile_lval() {
     struct A { int n; };
-    constexpr A a = {0}; // expected-note {{here}}
+    constexpr A a = {0}; // #dr2083-a2
     struct B {
       void f() {
         // An lvalue-to-rvalue conversion of a volatile lvalue always results
@@ -254,7 +299,9 @@ namespace dr2083 { // dr2083: partial
         int A::*p = &A::n;
         int x = a.*p;
         volatile int A::*q = p;
-        int y = a.*q; // expected-error {{enclosing function}}
+        int y = a.*q;
+        // since-cxx11-error at -1 {{reference to local variable 'a' declared in enclosing function 'dr2083::volatile_lval'}}
+        //   since-cxx11-note@#dr2083-a2 {{'a' declared here}}
       }
     };
   }
@@ -262,32 +309,45 @@ namespace dr2083 { // dr2083: partial
 
   void discarded_lval() {
     struct A { int x; mutable int y; volatile int z; };
-    A a; // expected-note 1+{{here}}
-    int &r = a.x; // expected-note {{here}}
+    A a; // #dr2083-a-3
+    int &r = a.x; // #dr2083-r
     struct B {
       void f() {
-        a.x; // expected-warning {{unused}}
-        a.*&A::x; // expected-warning {{unused}}
-        true ? a.x : a.y; // expected-warning {{unused}}
+        // FIXME: We emit more errors than we should be. They are explictly marked below.
+        a.x;
+        // expected-warning at -1 {{expression result unused}}
+        // expected-error at -2 {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}} FIXME
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
+        a.*&A::x;
+        // expected-warning at -1 {{expression result unused}}
+        // expected-error at -2 {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}} FIXME
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
+        true ? a.x : a.y; // #dr2083-ternary
+        // expected-warning at -1 {{expression result unused}}
+        // expected-error@#dr2083-ternary {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}} FIXME
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
+        // expected-error@#dr2083-ternary {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}} FIXME
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
         (void)a.x;
-        a.x, discarded_lval(); // expected-warning {{left operand of comma operator has no effect}}
-#if 1 // FIXME: These errors are all incorrect; the above code is valid.
-      // expected-error at -6 {{enclosing function}}
-      // expected-error at -6 {{enclosing function}}
-      // expected-error at -6 2{{enclosing function}}
-      // expected-error at -6 {{enclosing function}}
-      // expected-error at -6 {{enclosing function}}
-#endif
+        // expected-error at -1 {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}} FIXME
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
+        a.x, discarded_lval();
+        // expected-warning at -1 {{left operand of comma operator has no effect}}
+        // expected-error at -2 {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}} FIXME
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
 
         // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.
-        a.z; // expected-error {{enclosing function}}
-#if __cplusplus < 201103L
-        // expected-warning at -2 {{assign into a variable}}
-#endif
+        a.z;
+        // cxx98-warning at -1 {{expression result unused; assign into a variable to force a volatile load}}
+        // expected-error at -2 {{reference to local variable 'a' declared in enclosing function 'dr2083::discarded_lval'}}
+        //   expected-note@#dr2083-a-3 {{'a' declared here}}
 
         // References always get "loaded" to determine what they reference,
         // even if the result is discarded.
-        r; // expected-error {{enclosing function}} expected-warning {{unused}}
+        r;
+        // expected-warning at -1 {{expression result unused}}
+        // expected-error at -2 {{reference to local variable 'r' declared in enclosing function 'dr2083::discarded_lval'}}
+        //   expected-note@#dr2083-r {{'r' declared here}}
       }
     };
   }
@@ -295,12 +355,11 @@ namespace dr2083 { // dr2083: partial
   namespace dr_example_1 {
     extern int globx;
     int main() {
-      const int &x = globx;
+      const int &x = globx; // #dr2083-x
       struct A {
-#if __cplusplus < 201103L
-        // expected-error at +2 {{enclosing function}} expected-note at -3 {{here}}
-#endif
         const int *foo() { return &x; }
+        // cxx98-error at -1 {{reference to local variable 'x' declared in enclosing function 'dr2083::dr_example_1::main'}}
+        //   cxx98-note@#dr2083-x {{'x' declared here}}
       } a;
       return *a.foo();
     }
diff --git a/clang/test/CXX/drs/dr21xx.cpp b/clang/test/CXX/drs/dr21xx.cpp
index a1b8fe3f2a9be9..a7e50df3f374be 100644
--- a/clang/test/CXX/drs/dr21xx.cpp
+++ b/clang/test/CXX/drs/dr21xx.cpp
@@ -1,13 +1,14 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-
-#if __cplusplus < 201103L
-// expected-error at +1 {{variadic macro}}
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx98 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus == 199711L
 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error at -1 {{variadic macros are a C99 feature}}
 #endif
 
 namespace dr2100 { // dr2100: 12
@@ -18,15 +19,14 @@ namespace dr2100 { // dr2100: 12
       return X<&n>::n; // ok, value-dependent
     }
     int g() {
-      static const int n = 2;
+      static const int n = 2; // #dr2100-n
       return X<&n>::n; // ok, value-dependent
-#if __cplusplus < 201702L
-      // expected-error at -2 {{does not have linkage}} expected-note at -3 {{here}}
-#endif
+      // cxx98-14-error at -1 {{non-type template argument refers to object 'n' that does not have linkage}}
+      //   cxx98-14-note@#dr2100-n {{non-type template argument refers to object here}}
     }
   };
   template<const int *P> struct X<P> {
-#if __cplusplus < 201103L
+#if __cplusplus == 199711L
     static const int n = 0;
 #else
     static const int n = *P;
@@ -40,11 +40,13 @@ namespace dr2100 { // dr2100: 12
   template<typename T> struct B {
     static const int n = 1;
     int f() {
-      return Y<n>::declared_later; // expected-error {{no member named 'declared_later'}}
+      return Y<n>::declared_later;
+      // expected-error at -1 {{no member named 'declared_later' in 'dr2100::Y<1>'}}
     }
     int g() {
       static const int n = 2;
-      return Y<n>::declared_later; // expected-error {{no member named 'declared_later'}}
+      return Y<n>::declared_later;
+      // expected-error at -1 {{no member named 'declared_later' in 'dr2100::Y<2>'}}
     }
   };
   template<int N> struct Y<N> {
@@ -55,10 +57,12 @@ namespace dr2100 { // dr2100: 12
 namespace dr2103 { // dr2103: yes
   void f() {
     int a;
-    int &r = a; // expected-note {{here}}
+    int &r = a; // #dr2103-r
     struct Inner {
       void f() {
-        int &s = r; // expected-error {{enclosing function}}
+        int &s = r;
+        // expected-error at -1 {{reference to local variable 'r' declared in enclosing function 'dr2103::f'}}
+        //   expected-note@#dr2103-r {{'r' declared here}}
         (void)s;
       }
     };
@@ -84,28 +88,46 @@ namespace dr2126 { // dr2126: 12
   A &b = (A &)(const A &)A{1};   // const temporary
   A &&c = (A &&)(const A &)A{1}; // const temporary
 
-  A &&d = {1};                   // non-const temporary expected-note {{here}}
-  const A &e = (A &)(A &&) A{1}; // non-const temporary expected-note {{here}}
-  A &&f = (A &&)(A &&) A{1};     // non-const temporary expected-note {{here}}
+  A &&d = {1};                   // non-const temporary #dr21260-d
+  const A &e = (A &)(A &&) A{1}; // non-const temporary #dr21260-e
+  A &&f = (A &&)(A &&) A{1};     // non-const temporary #dr21260-f
 
   constexpr const A &g = {1};    // const temporary
-  constexpr A &&h = {1};         // non-const temporary expected-note {{here}}
+  constexpr A &&h = {1};         // non-const temporary #dr21260-h
 
   struct B { const A &a; };
-  B i = {{1}};           // extending decl not usable in constant expr expected-note {{here}}
-  const B j = {{1}};     // extending decl not usable in constant expr expected-note {{here}}
+  B i = {{1}};           // extending decl not usable in constant expr #dr21260-i
+  const B j = {{1}};     // extending decl not usable in constant expr #dr21260-j
   constexpr B k = {{1}}; // extending decl usable in constant expr
 
   static_assert(a.n == 1, "");
   static_assert(b.n == 1, "");
   static_assert(c.n == 1, "");
-  static_assert(d.n == 1, ""); // expected-error {{constant}} expected-note {{read of temporary}}
-  static_assert(e.n == 1, ""); // expected-error {{constant}} expected-note {{read of temporary}}
-  static_assert(f.n == 1, ""); // expected-error {{constant}} expected-note {{read of temporary}}
+  static_assert(d.n == 1, "");
+  // since-cxx11-error at -1 {{static assertion expression is not an integral constant expression}}
+  //   since-cxx11-note at -2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
+  //   since-cxx11-note@#dr21260-d {{temporary created here}}
+  static_assert(e.n == 1, "");
+  // since-cxx11-error at -1 {{static assertion expression is not an integral constant expression}}
+  //   since-cxx11-note at -2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
+  //   since-cxx11-note@#dr21260-e {{temporary created here}}
+  static_assert(f.n == 1, "");
+  // since-cxx11-error at -1 {{static assertion expression is not an integral constant expression}}
+  //   since-cxx11-note at -2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
+  //   since-cxx11-note@#dr21260-f {{temporary created here}}
   static_assert(g.n == 1, "");
-  static_assert(h.n == 1, ""); // expected-error {{constant}} expected-note {{read of temporary}}
-  static_assert(i.a.n == 1, ""); // expected-error {{constant}} expected-note {{read of non-constexpr variable}}
-  static_assert(j.a.n == 1, ""); // expected-error {{constant}} expected-note {{read of temporary}}
+  static_assert(h.n == 1, "");
+  // since-cxx11-error at -1 {{static assertion expression is not an integral constant expression}}
+  //   since-cxx11-note at -2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
+  //   since-cxx11-note@#dr21260-h {{temporary created here}}
+  static_assert(i.a.n == 1, "");
+  // since-cxx11-error at -1 {{static assertion expression is not an integral constant expression}}
+  //   since-cxx11-note at -2 {{read of non-constexpr variable 'i' is not allowed in a constant expression}}
+  //   since-cxx11-note@#dr21260-i {{declared here}}
+  static_assert(j.a.n == 1, "");
+  // since-cxx11-error at -1 {{static assertion expression is not an integral constant expression}}
+  //   since-cxx11-note at -2 {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}
+  //   since-cxx11-note@#dr21260-j {{temporary created here}}
   static_assert(k.a.n == 1, "");
 #endif
 }
@@ -128,19 +150,27 @@ struct B{};
 
 void foo() {
   struct A *b = (1 == 1) ? new struct A : new struct A;
-  struct S *a = (1 == 1) ? new struct S : new struct S; // expected-error 2{{allocation of incomplete type}} // expected-note 2{{forward}}
+  struct S *a = (1 == 1) ? new struct S : new struct S;
+  // expected-error at -1 {{allocation of incomplete type 'struct S'}}
+  //   expected-note at -2 {{forward declaration of 'S'}}
+  // expected-error at -3 {{allocation of incomplete type 'struct S'}}
+  //   expected-note at -4 {{forward declaration of 'S'}}
 
 #if __cplusplus >= 201103L
   A *aa = new struct A{};
   B<int> *bb = new struct B<int>{};
-  (void)new struct C{}; // expected-error {{allocation of incomplete type }} // expected-note {{forward}}
+  (void)new struct C{};
+  // since-cxx11-error at -1 {{allocation of incomplete type 'struct C'}}
+  //   since-cxx11-note at -2 {{forward declaration of 'C'}}
 
   struct A *c = (1 == 1) ? new struct A {} : new struct A {};
 
-  alignof(struct D{}); // expected-error {{cannot be defined in a type specifier}}
+  alignof(struct D{});
+  // since-cxx11-error at -1 {{'D' cannot be defined in a type specifier}}
 #endif
 
-  sizeof(struct E{}); // expected-error {{cannot be defined in a type specifier}}
+  sizeof(struct E{});
+  // expected-error at -1 {{'E' cannot be defined in a type specifier}}
 
 }
 }
@@ -149,7 +179,8 @@ namespace dr2157 { // dr2157: 11
 #if __cplusplus >= 201103L
   enum E : int;
   struct X {
-    enum dr2157::E : int(); // expected-error {{only allows ':' in member enumeration declaration to introduce a fixed underlying type}}
+    enum dr2157::E : int();
+    // since-cxx11-error at -1 {{ISO C++ only allows ':' in member enumeration declaration to introduce a fixed underlying type, not an anonymous bit-field}}
   };
 #endif
 }
@@ -159,11 +190,13 @@ namespace dr2157 { // dr2157: 11
 namespace dr2170 { // dr2170: 9
 #if __cplusplus >= 201103L
   void f() {
-    constexpr int arr[3] = {1, 2, 3}; // expected-note {{here}}
+    constexpr int arr[3] = {1, 2, 3}; // #dr2170-arr
     struct S {
       int get(int n) { return arr[n]; }
-      const int &get_ref(int n) { return arr[n]; } // expected-error {{enclosing function}}
-      // FIXME: expected-warning at -1 {{reference to stack}}
+      const int &get_ref(int n) { return arr[n]; }
+      // since-cxx11-warning at -1 {{reference to stack memory associated with local variable 'arr' returned}} FIXME
+      // since-cxx11-error at -2 {{reference to local variable 'arr' declared in enclosing function 'dr2170::f'}}
+      //   since-cxx11-note@#dr2170-arr {{'arr' declared here}}
     };
   }
 #endif
@@ -198,22 +231,32 @@ static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
 
 namespace dr2180 { // dr2180: yes
   class A {
-    A &operator=(const A &); // expected-note 0-2{{here}}
-    A &operator=(A &&); // expected-note 0-2{{here}} expected-error 0-1{{extension}}
+    A &operator=(const A &); // #dr2180-A-copy
+    A &operator=(A &&); // #dr2180-A-move
+    // cxx98-error at -1 {{rvalue references are a C++11 extension}}
   };
 
-  struct B : virtual A {
+  struct B : virtual A { // #dr2180-B
     B &operator=(const B &);
-    B &operator=(B &&); // expected-error 0-1{{extension}}
+    B &operator=(B &&);
+    // cxx98-error at -1 {{rvalue references are a C++11 extension}}
     virtual void foo() = 0;
   };
-#if __cplusplus < 201103L
-  B &B::operator=(const B&) = default; // expected-error {{private member}} expected-error {{extension}} expected-note {{here}}
-  B &B::operator=(B&&) = default; // expected-error {{private member}} expected-error 2{{extension}} expected-note {{here}}
-#else
-  B &B::operator=(const B&) = default; // expected-error {{would delete}} expected-note at -9{{inaccessible copy assignment}}
-  B &B::operator=(B&&) = default; // expected-error {{would delete}} expected-note at -10{{inaccessible move assignment}}
-#endif
+  B &B::operator=(const B&) = default; // #dr2180-B-copy
+  // cxx98-error at -1 {{defaulted function definitions are a C++11 extension}}
+  // cxx98-error at -2 {{'operator=' is a private member of 'dr2180::A'}}
+  //   cxx98-note at -3 {{in defaulted copy assignment operator for 'dr2180::B' first required here}}
+  //   cxx98-note@#dr2180-A-copy {{implicitly declared private here}}
+  // since-cxx11-error@#dr2180-B-copy {{defaulting this copy assignment operator would delete it after its first declaration}}
+  //   since-cxx11-note@#dr2180-B {{copy assignment operator of 'B' is implicitly deleted because base class 'A' has an inaccessible copy assignment operator}}
+  B &B::operator=(B&&) = default; // #dr2180-B-move
+  // cxx98-error at -1 {{rvalue references are a C++11 extension}}
+  // cxx98-error at -2 {{defaulted function definitions are a C++11 extension}}
+  // cxx98-error at -3 {{'operator=' is a private member of 'dr2180::A'}}
+  //   cxx98-note at -4 {{in defaulted move assignment operator for 'dr2180::B' first required here}}
+  //   cxx98-note@#dr2180-A-move {{implicitly declared private here}}
+  // since-cxx11-error@#dr2180-B-move {{defaulting this move assignment operator would delete it after its first declaration}}
+  //   since-cxx11-note@#dr2180-B {{move assignment operator of 'B' is implicitly deleted because base class 'A' has an inaccessible move assignment operator}}
 }
 
 namespace dr2199 { // dr2199: 3.8
diff --git a/clang/test/CXX/drs/dr22xx.cpp b/clang/test/CXX/drs/dr22xx.cpp
index cd849443b1119b..19518247b5289c 100644
--- a/clang/test/CXX/drs/dr22xx.cpp
+++ b/clang/test/CXX/drs/dr22xx.cpp
@@ -1,14 +1,19 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+
 
 #if __cplusplus >= 201103L
 namespace dr2211 { // dr2211: 8
 void f() {
   int a;
-  auto f = [a](int a) { (void)a; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
-  // expected-note at -1{{variable 'a' is explicitly captured here}}
+  auto f = [a](int a) { (void)a; };
+  // since-cxx11-error at -1 {{a lambda parameter cannot shadow an explicitly captured entity}}
+  //   since-cxx11-note at -2 {{variable 'a' is explicitly captured here}}
   auto g = [=](int a) { (void)a; };
 }
 }
@@ -24,9 +29,12 @@ struct A<int, U>;
 
 namespace dr2229 { // dr2229: 7
 struct AnonBitfieldQualifiers {
-  const unsigned : 1; // expected-error {{anonymous bit-field cannot have qualifiers}}
-  volatile unsigned : 1; // expected-error {{anonymous bit-field cannot have qualifiers}}
-  const volatile unsigned : 1; // expected-error {{anonymous bit-field cannot have qualifiers}}
+  const unsigned : 1;
+  // expected-error at -1 {{anonymous bit-field cannot have qualifiers}}
+  volatile unsigned : 1;
+  // expected-error at -1 {{anonymous bit-field cannot have qualifiers}}
+  const volatile unsigned : 1;
+  // expected-error at -1 {{anonymous bit-field cannot have qualifiers}}
 
   unsigned : 1;
   const unsigned i1 : 1;
@@ -98,7 +106,8 @@ namespace MultilevelSpecialization {
     template <T... V> void f(int i = 0, int (&... arr)[V]);
   };
   template<> template<int a, int b>
-    void B<int, int>::f(int i, int (&arr1)[a], int (&arr2)[b]) {} // expected-error {{does not match}}
+    void B<int, int>::f(int i, int (&arr1)[a], int (&arr2)[b]) {}
+    // since-cxx11-error at -1 {{out-of-line definition of 'f' does not match any declaration in 'dr2233::MultilevelSpecialization::B<int, int>'}}
   template<> template<>
     void B<int, int>::f<1, 1>(int i, int (&arr1a)[1], int (&arr2a)[1]) {}
 }
@@ -134,10 +143,10 @@ struct C { explicit operator D(); } c;
 B b1(a);
 const B &b2{a}; // FIXME ill-formed
 const B &b3(a);
-// expected-error at -1 {{no viable conversion from 'struct A' to 'const B'}}
-// expected-note@#dr2267-struct-B {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const B &' for 1st argument}}
-// expected-note@#dr2267-struct-B {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'B &&' for 1st argument}}
-// expected-note@#dr2267-struct-B {{explicit constructor is not a candidate}}
+// since-cxx11-error at -1 {{no viable conversion from 'struct A' to 'const B'}}
+//   since-cxx11-note@#dr2267-struct-B {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const B &' for 1st argument}}
+//   since-cxx11-note@#dr2267-struct-B {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'B &&' for 1st argument}}
+//   since-cxx11-note@#dr2267-struct-B {{explicit constructor is not a candidate}}
 
 D d1(c);
 const D &d2{c}; // FIXME ill-formed
diff --git a/clang/test/CXX/drs/dr2354.cpp b/clang/test/CXX/drs/dr2354.cpp
deleted file mode 100644
index 3efb0ba5556690..00000000000000
--- a/clang/test/CXX/drs/dr2354.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -x c++ -verify %s 
-
-// dr2354: 15
-
-namespace DR2354 {
-
-enum alignas(64) A {};        // expected-error {{'alignas' attribute cannot be applied to an enumeration}}
-enum struct alignas(64) B {}; // expected-error {{'alignas' attribute cannot be applied to an enumeration}}
-
-} // namespace DR2354
diff --git a/clang/test/CXX/drs/dr23xx.cpp b/clang/test/CXX/drs/dr23xx.cpp
index 6cb10067739f8e..9ced61d2aae30d 100644
--- a/clang/test/CXX/drs/dr23xx.cpp
+++ b/clang/test/CXX/drs/dr23xx.cpp
@@ -1,9 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
 
 #if __cplusplus >= 201103L
 namespace dr2303 { // dr2303: 12
@@ -14,8 +15,14 @@ struct A<> {};
 template <typename T, typename... Ts>
 struct A<T, Ts...> : A<Ts...> {};
 struct B : A<int, int> {};
-struct C : A<int, int>, A<int> {}; // expected-warning {{direct base 'A<int>' is inaccessible}}
-struct D : A<int>, A<int, int> {}; // expected-warning {{direct base 'A<int>' is inaccessible}}
+struct C : A<int, int>, A<int> {};
+/* since-cxx11-warning at -1 {{direct base 'A<int>' is inaccessible due to ambiguity:
+    struct dr2303::C -> A<int, int> -> A<int>
+    struct dr2303::C -> A<int>}} */
+struct D : A<int>, A<int, int> {};
+/* since-cxx11-warning at -1 {{direct base 'A<int>' is inaccessible due to ambiguity:
+    struct dr2303::D -> A<int>
+    struct dr2303::D -> A<int, int> -> A<int>}} */
 struct E : A<int, int> {};
 struct F : B, E {};
 
@@ -32,7 +39,10 @@ void g() {
   f2(&b);
   f(C{});
   f(D{});
-  f(F{}); // expected-error {{ambiguous conversion from derived class}}
+  f(F{});
+  /* since-cxx11-error at -1 {{ambiguous conversion from derived class 'const F' to base class 'const A<int, int>':
+    struct dr2303::F -> B -> A<int, int>
+    struct dr2303::F -> E -> A<int, int>}} */
 }
 } //namespace dr2303
 #endif
@@ -65,8 +75,10 @@ namespace dr2352 { // dr2352: 10
   int *const *const &f2() { return p; }
   int **const &f3() { return p; }
 
-  const int **const &f4() { return p; } // expected-error {{reference to type 'const int **const' could not bind to an lvalue of type 'int **'}}
-  const int *const *&f5() { return p; } // expected-error {{binding reference of type 'const int *const *' to value of type 'int **' not permitted due to incompatible qualifiers}}
+  const int **const &f4() { return p; }
+  // expected-error at -1 {{reference to type 'const int **const' could not bind to an lvalue of type 'int **'}}
+  const int *const *&f5() { return p; }
+  // expected-error at -1 {{binding reference of type 'const int *const *' to value of type 'int **' not permitted due to incompatible qualifiers}}
 
   // FIXME: We permit this as a speculative defect resolution, allowing
   // qualification conversions when forming a glvalue conditional expression.
@@ -76,7 +88,8 @@ namespace dr2352 { // dr2352: 10
   // FIXME: Should we compute the composite pointer type here and produce an
   // lvalue of type 'const int *const * const'?
   const int * const * r;
-  void *y = &(true ? p : r); // expected-error {{rvalue of type 'const int *const *'}}
+  void *y = &(true ? p : r);
+  // expected-error at -1 {{rvalue of type 'const int *const *'}}
 
   // FIXME: We order these as a speculative defect resolution.
   void f(const int * const * const &r);
@@ -124,12 +137,22 @@ namespace dr2353 { // dr2353: 9
 #pragma clang __debug dump not_use_2
 }
 
+namespace dr2354 { // dr2354: 15
+#if __cplusplus >= 201103L
+enum alignas(64) A {};
+// since-cxx11-error at -1 {{'alignas' attribute cannot be applied to an enumeration}}
+enum struct alignas(64) B {};
+// since-cxx11-error at -1 {{'alignas' attribute cannot be applied to an enumeration}}
+#endif
+} // namespace dr2354
+
 #if __cplusplus >= 201402L
 namespace dr2358 { // dr2358: 16
   void f2() {
     int i = 1;
     void g1(int = [xxx=1] { return xxx; }());  // OK
-    void g2(int = [xxx=i] { return xxx; }());  // expected-error {{default argument references local variable 'i' of enclosing function}}
+    void g2(int = [xxx=i] { return xxx; }());
+    // since-cxx14-error at -1 {{default argument references local variable 'i' of enclosing function}}
   }
 }
 #endif
@@ -148,7 +171,7 @@ class C {
 };
 } // namespace dr2370
 
-#if __cplusplus >= 201707L
+#if __cplusplus >= 201702L
 // Otherwise, if the qualified-id std::tuple_size<E> names a complete class
 // type **with a member value**, the expression std::tuple_size<E>::value shall
 // be a well-formed integral constant expression
@@ -165,7 +188,8 @@ template <> struct std::tuple_size<dr2386::Bad2> {
 } // namespace std
 namespace dr2386 {
 void no_value() { auto [x, y] = Bad1(); }
-void wrong_value() { auto [x, y] = Bad2(); } // expected-error {{decomposes into 42 elements}}
+void wrong_value() { auto [x, y] = Bad2(); }
+// since-cxx17-error at -1 {{type 'Bad2' decomposes into 42 elements, but only 2 names were provided}}
 } // namespace dr2386
 #endif
 
@@ -177,7 +201,8 @@ namespace dr2387 { // dr2387: 9
   extern template int a<0>; // ok
 
   template<int> static int b = 0;
-  extern template int b<0>; // expected-error {{internal linkage}}
+  extern template int b<0>;
+  // since-cxx14-error at -1 {{explicit instantiation declaration of 'b<0>' with internal linkage}}
 
   template<int> const int c = 0;
   extern template const int c<0>; // ok, has external linkage despite 'const'
diff --git a/clang/test/CXX/drs/dr2406.cpp b/clang/test/CXX/drs/dr2406.cpp
deleted file mode 100644
index 0ab198e6f1498e..00000000000000
--- a/clang/test/CXX/drs/dr2406.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// RUN: %clang_cc1 -x c++ %s  -verify
-
-// dr2406: 5
-
-void fallthrough(int n) {
-  void g(), h(), i();
-  switch (n) {
-  case 1:
-  case 2:
-    g();
-    [[fallthrough]];
-  case 3: // warning on fallthrough discouraged
-    do {
-      [[fallthrough]]; // expected-error {{fallthrough annotation does not directly precede switch label}}
-    } while (false);
-  case 6:
-    do {
-      [[fallthrough]]; // expected-error {{fallthrough annotation does not directly precede switch label}}
-    } while (n);
-  case 7:
-    while (false) {
-      [[fallthrough]]; // expected-error {{fallthrough annotation does not directly precede switch label}}
-    }
-  case 5:
-    h();
-  case 4: // implementation may warn on fallthrough
-    i();
-    [[fallthrough]]; // expected-error {{fallthrough annotation does not directly precede switch label}}
-  }
-}
diff --git a/clang/test/CXX/drs/dr24xx.cpp b/clang/test/CXX/drs/dr24xx.cpp
index 3fd8539be53d81..b34ceb420788fc 100644
--- a/clang/test/CXX/drs/dr24xx.cpp
+++ b/clang/test/CXX/drs/dr24xx.cpp
@@ -1,9 +1,52 @@
-// RUN: %clang_cc1 -std=c++20 %s -verify
-// RUN: %clang_cc1 -std=c++23 %s -verify
+// RUN: %clang_cc1 -std=c++98 %s -verify=expected
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected
+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx17
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx17
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx17
+
+#if __cplusplus <= 201402L
 // expected-no-diagnostics
+#endif
+
+namespace dr2406 { // dr2406: 5
+#if __cplusplus >= 201703L
+void fallthrough(int n) {
+  void g(), h(), i();
+  switch (n) {
+  case 1:
+  case 2:
+    g();
+    [[fallthrough]];
+  case 3: // warning on fallthrough discouraged
+    do {
+      [[fallthrough]];
+      // since-cxx17-error at -1 {{fallthrough annotation does not directly precede switch label}}
+    } while (false);
+  case 6:
+    do {
+      [[fallthrough]];
+      // since-cxx17-error at -1 {{fallthrough annotation does not directly precede switch label}}
+    } while (n);
+  case 7:
+    while (false) {
+      [[fallthrough]];
+      // since-cxx17-error at -1 {{fallthrough annotation does not directly precede switch label}}
+    }
+  case 5:
+    h();
+  case 4: // implementation may warn on fallthrough
+    i();
+    [[fallthrough]];
+    // since-cxx17-error at -1 {{fallthrough annotation does not directly precede switch label}}
+  }
+}
+#endif
+}
 
 namespace dr2450 { // dr2450: 18 drafting
-#if __cplusplus > 202002L
+#if __cplusplus >= 202302L
 struct S {int a;};
 template <S s>
 void f(){}
@@ -17,7 +60,7 @@ f<{.a= 0}>();
 }
 
 namespace dr2459 { // dr2459: 18 drafting
-#if __cplusplus > 202002L
+#if __cplusplus >= 202302L
 struct A {
   constexpr A(float) {}
 };
diff --git a/clang/test/CXX/drs/dr25xx.cpp b/clang/test/CXX/drs/dr25xx.cpp
index 0204ecaf636180..8c34b03c22d5b1 100644
--- a/clang/test/CXX/drs/dr25xx.cpp
+++ b/clang/test/CXX/drs/dr25xx.cpp
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-
-#if __cplusplus < 201103L
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus == 199711L
 // expected-no-diagnostics
 #endif
 
@@ -17,7 +17,7 @@ template <typename T> struct S {
   typedef char I;
 };
 enum E2 : S<E2>::I { e };
-// expected-error at -1 {{use of undeclared identifier 'E2'}}
+// since-cxx11-error at -1 {{use of undeclared identifier 'E2'}}
 #endif
 } // namespace dr2516
 
@@ -27,24 +27,24 @@ namespace dr2518 { // dr2518: 17
 template <class T>
 void f(T t) {
   if constexpr (sizeof(T) != sizeof(int)) {
-#if __cplusplus < 201703L
-// expected-error at -2 {{constexpr if is a C++17 extension}}
-#endif
-    static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
+  // cxx11-14-error at -1 {{constexpr if is a C++17 extension}}
+    static_assert(false, "must be int-sized");
+    // since-cxx11-error at -1 {{static assertion failed: must be int-sized}}
+    //   since-cxx11-note@#dr2518-f-c {{in instantiation of function template specialization 'dr2518::f<char>' requested here}}
   }
 }
 
 void g(char c) {
   f(0);
-  f(c); // expected-note {{requested here}}
+  f(c); // #dr2518-f-c
 }
 
 template <typename Ty>
 struct S {
-  static_assert(false); // expected-error {{static assertion failed}}
-#if __cplusplus < 201703L
-// expected-error at -2 {{'static_assert' with no message is a C++17 extension}}
-#endif
+  static_assert(false);
+  // cxx11-14-error at -1 {{'static_assert' with no message is a C++17 extension}}
+  // since-cxx11-error at -2 {{static assertion failed}}
+  //   since-cxx11-note@#dr2518-S-double {{in instantiation of template class 'dr2518::S<double>' requested here}}
 };
 
 template <>
@@ -56,7 +56,7 @@ struct S<float> {};
 int test_specialization() {
   S<int> s1;
   S<float> s2;
-  S<double> s3; // expected-note {{in instantiation of template class 'dr2518::S<double>' requested here}}
+  S<double> s3; // #dr2518-S-double
 }
 #endif
 
@@ -67,16 +67,16 @@ namespace dr2521 { // dr2521: 17
 #pragma clang diagnostic push
 #pragma clang diagnostic warning "-Wdeprecated-literal-operator"
 long double operator""      _\u03C0___(long double);
-// expected-warning at -1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
-// expected-warning at -2 {{user-defined literal suffixes containing '__' are reserved}}
+// since-cxx11-warning at -1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
+// since-cxx11-warning at -2 {{user-defined literal suffixes containing '__' are reserved}}
 
 template <char... Chars> decltype(sizeof 0)
 operator""  _div();
-// expected-warning at -1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}}
+// since-cxx11-warning at -1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}}
 
 using ::dr2521::operator"" _\u03C0___;
 using ::dr2521::operator""_div;
-// expected-warning at -2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
+// since-cxx11-warning at -2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
 #pragma clang diagnostic pop
 #endif
 } // namespace dr2521
@@ -85,12 +85,16 @@ using ::dr2521::operator""_div;
 #if __cplusplus >= 202302L
 namespace dr2553 { // dr2553: 18
 struct B {
-  virtual void f(this B&);   // expected-error {{an explicit object parameter cannot appear in a virtual function}}
-  static void f(this B&);   // expected-error {{an explicit object parameter cannot appear in a static function}}
-  virtual void g(); // expected-note {{here}}
+  virtual void f(this B&); 
+  // since-cxx23-error at -1 {{an explicit object parameter cannot appear in a virtual function}}
+  static void f(this B&);
+  // since-cxx23-error at -1 {{an explicit object parameter cannot appear in a static function}}
+  virtual void g(); // #dr2553-g
 };
 struct D : B {
-  void g(this D&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
+  void g(this D&);
+  // since-cxx23-error at -1 {{an explicit object parameter cannot appear in a virtual function}}
+  //   since-cxx23-note@#dr2553-g {{overridden virtual function is here}}
 };
 
 }
@@ -99,19 +103,25 @@ struct D : B {
 #if __cplusplus >= 202302L
 namespace dr2554 { // dr2554: 18 review
 struct B {
-  virtual void f(); // expected-note 3{{here}}
+  virtual void f(); // #dr2554-g
 };
 
 struct D : B {
-  void f(this D&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
+  void f(this D&);
+  // since-cxx23-error at -1 {{an explicit object parameter cannot appear in a virtual function}}
+  //   since-cxx23-note@#dr2554-g {{overridden virtual function is here}}
 };
 
 struct D2 : B {
-  void f(this B&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
+  void f(this B&);
+  // since-cxx23-error at -1 {{an explicit object parameter cannot appear in a virtual function}}
+  //   since-cxx23-note@#dr2554-g {{overridden virtual function is here}}
 };
 struct T {};
 struct D3 : B {
-  void f(this T&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
+  void f(this T&);
+  // since-cxx23-error at -1 {{an explicit object parameter cannot appear in a virtual function}}
+  //   since-cxx23-note@#dr2554-g {{overridden virtual function is here}}
 };
 
 }
@@ -153,48 +163,48 @@ namespace dr2565 { // dr2565: 16
   static_assert(is_referenceable<int>::value);
 
   template<typename T, typename U>
-  concept TwoParams = requires (T *a, U b){ true;}; // #TPC
+  concept TwoParams = requires (T *a, U b){ true;}; // #dr2565-TPC
 
   template<typename T, typename U>
-    requires TwoParams<T, U> // #TPSREQ
+    requires TwoParams<T, U> // #dr2565-TPSREQ
   struct TwoParamsStruct{};
 
   using TPSU = TwoParamsStruct<void, void>;
-  // expected-error at -1{{constraints not satisfied for class template 'TwoParamsStruct'}}
-  // expected-note@#TPSREQ{{because 'TwoParams<void, void>' evaluated to false}}
-  // expected-note@#TPC{{because 'b' would be invalid: argument may not have 'void' type}}
+  // since-cxx20-error at -1 {{constraints not satisfied for class template 'TwoParamsStruct'}}
+  //   since-cxx20-note@#dr2565-TPSREQ {{because 'TwoParams<void, void>' evaluated to false}}
+  //   since-cxx20-note@#dr2565-TPC {{because 'b' would be invalid: argument may not have 'void' type}}
 
   template<typename T, typename ...U>
-  concept Variadic = requires (U* ... a, T b){ true;}; // #VC
+  concept Variadic = requires (U* ... a, T b){ true;}; // #dr2565-VC
 
   template<typename T, typename ...U>
-    requires Variadic<T, U...> // #VSREQ
+    requires Variadic<T, U...> // #dr2565-VSREQ
   struct VariadicStruct{};
 
   using VSU = VariadicStruct<void, int, char, double>;
-  // expected-error at -1{{constraints not satisfied for class template 'VariadicStruct'}}
-  // expected-note@#VSREQ{{because 'Variadic<void, int, char, double>' evaluated to false}}
-  // expected-note@#VC{{because 'b' would be invalid: argument may not have 'void' type}}
+  // since-cxx20-error at -1 {{constraints not satisfied for class template 'VariadicStruct'}}
+  //   since-cxx20-note@#dr2565-VSREQ {{because 'Variadic<void, int, char, double>' evaluated to false}}
+  //   since-cxx20-note@#dr2565-VC {{because 'b' would be invalid: argument may not have 'void' type}}
 
   template<typename T>
-  // expected-error at +1 {{unknown type name 'ErrorRequires'}}
   concept ErrorRequires = requires (ErrorRequires auto x) {
+  // since-cxx20-error at -1 {{unknown type name 'ErrorRequires'}}
     x;
   };
   static_assert(ErrorRequires<int>);
-  // expected-error at -1{{static assertion failed}}
-  // expected-note at -2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
+  // since-cxx20-error at -1 {{static assertion failed}}
+  //   since-cxx20-note at -2 {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
   template<typename T>
-  // expected-error at +2 {{unknown type name 'NestedErrorInRequires'}}
   concept NestedErrorInRequires = requires (T x) {
     requires requires (NestedErrorInRequires auto y) {
+    // since-cxx20-error at -1 {{unknown type name 'NestedErrorInRequires'}}
       y;
     };
   };
   static_assert(NestedErrorInRequires<int>);
-  // expected-error at -1{{static assertion failed}}
-  // expected-note at -2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
+  // expected-error at -1 {{static assertion failed}}
+  //   expected-note at -2 {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
 
 #endif
 }
diff --git a/clang/test/CXX/drs/dr26xx.cpp b/clang/test/CXX/drs/dr26xx.cpp
index 1d702e66bf8c7f..dd4bb1ff6ae2e1 100644
--- a/clang/test/CXX/drs/dr26xx.cpp
+++ b/clang/test/CXX/drs/dr26xx.cpp
@@ -1,8 +1,14 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
-// RUN: %clang_cc1 -std=c++2b -triple x86_64-unknown-unknown %s -verify
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23
 
 
 namespace dr2621 { // dr2621: 16
+#if __cplusplus >= 202002L
 enum class E { a };
 namespace One {
 using E_t = E;
@@ -12,33 +18,39 @@ auto v = a;
 namespace Two {
 using dr2621::E;
 int E; // we see this
-using enum E; // expected-error {{unknown type name E}}
+using enum E;
+// since-cxx20-error at -1 {{unknown type name E}}
 }
+#endif
 }
 
 namespace dr2628 { // dr2628: no open
                    // this was reverted for the 16.x release
                    // due to regressions, see the issue for more details:
                    // https://github.com/llvm/llvm-project/issues/60777
-
+#if __cplusplus >= 202002L
 template <bool A = false, bool B = false>
 struct foo {
   // The expected notes below should be removed when dr2628 is fully implemented again
-  constexpr foo() requires (!A && !B) = delete; // expected-note {{candidate function [with A = false, B = false]}} #DR2628_CTOR
-  constexpr foo() requires (A || B) = delete; // expected-note {{candidate function [with A = false, B = false]}}
+  constexpr foo() requires (!A && !B) = delete; // #dr2628-ctor-1
+  constexpr foo() requires (A || B) = delete; //  #dr2628-ctor-2
 };
 
 void f() {
   // The FIXME's below should be the expected errors when dr2628 is
   // fully implemented again.
-  // FIXME-expected-error {{call to deleted}}
-  foo fooable; // expected-error {{ambiguous deduction for template arguments of 'foo'}}
-  // FIXME-expected-note@#DR2628_CTOR {{marked deleted here}}
+  foo fooable; // #dr2628-fooable
+  // since-cxx20-error at -1 {{ambiguous deduction for template arguments of 'foo'}}
+  //   since-cxx20-note@#dr2628-ctor-1 {{candidate function [with A = false, B = false]}}
+  //   since-cxx20-note@#dr2628-ctor-2 {{candidate function [with A = false, B = false]}}
+  // FIXME-since-cxx20-error@#dr2628-fooable {{call to deleted}} 
+  //   FIXME-since-cxx20-note@#dr2628-ctor {{marked deleted here}} 
 }
-
+#endif
 }
 
 namespace dr2631 { // dr2631: 16
+#if __cplusplus >= 202002L
   constexpr int g();
   consteval int f() {
     return g();
@@ -52,9 +64,11 @@ namespace dr2631 { // dr2631: 16
   int test() {
     return k();
   }
+#endif
 }
 
 namespace dr2635 { // dr2635: 16
+#if __cplusplus >= 202002L
 template<typename T>
 concept UnaryC = true;
 template<typename T, typename U>
@@ -67,66 +81,79 @@ template<typename T>
 T get_T();
 
 void use() {
-  // expected-error at +1{{decomposition declaration cannot be declared with constrained 'auto'}}
   UnaryC auto [a, b] = get_S();
-  // expected-error at +1{{decomposition declaration cannot be declared with constrained 'auto'}}
+  // since-cxx20-error at -1 {{decomposition declaration cannot be declared with constrained 'auto'}}
   BinaryC<int> auto [c, d] = get_S();
+  // since-cxx20-error at -1 {{decomposition declaration cannot be declared with constrained 'auto'}}
 }
 
 template<typename T>
 void TemplUse() {
-  // expected-error at +1{{decomposition declaration cannot be declared with constrained 'auto'}}
   UnaryC auto [a, b] = get_T<T>();
-  // expected-error at +1{{decomposition declaration cannot be declared with constrained 'auto'}}
+  // since-cxx20-error at -1 {{decomposition declaration cannot be declared with constrained 'auto'}}
   BinaryC<T> auto [c, d] = get_T<T>();
+  // since-cxx20-error at -1 {{decomposition declaration cannot be declared with constrained 'auto'}}
 }
+#endif
 }
 
-  // dr2636: na
+// dr2636: na
 
 namespace dr2640 { // dr2640: 16
 
-int \N{Λ} = 0; //expected-error {{'Λ' is not a valid Unicode character name}} \
-               //expected-error {{expected unqualified-id}}
-const char* emoji = "\N{🤡}"; // expected-error {{'🤡' is not a valid Unicode character name}} \
-                              // expected-note 5{{did you mean}}
+int \N{Λ} = 0;
+// expected-error at -1 {{'Λ' is not a valid Unicode character name}}
+// expected-error at -2 {{expected unqualified-id}}
+const char* emoji = "\N{🤡}";
+// expected-error at -1 {{'🤡' is not a valid Unicode character name}}
+// expected-note at -2 {{did you mean OX ('🐂' U+1F402)?}}
+// expected-note at -3 {{did you mean ANT ('🐜' U+1F41C)?}}
+// expected-note at -4 {{did you mean ARC ('⌒' U+2312)?}}
+// expected-note at -5 {{did you mean AXE ('🪓' U+1FA93)?}}
+// expected-note at -6 {{did you mean BAT ('🦇' U+1F987)?}}
 
 #define z(x) 0
 #define dr2640_a z(
-int x = dr2640_a\N{abc}); // expected-error {{'abc' is not a valid Unicode character name}}
-int y = dr2640_a\N{LOTUS}); // expected-error {{character <U+1FAB7> not allowed in an identifier}} \
-                     // expected-error {{use of undeclared identifier 'dr2640_a🪷'}} \
-                     // expected-error {{extraneous ')' before ';'}}
+int x = dr2640_a\N{abc});
+// expected-error at -1 {{'abc' is not a valid Unicode character name}}
+int y = dr2640_a\N{LOTUS});
+// expected-error at -1 {{character <U+1FAB7> not allowed in an identifier}}
+// expected-error at -2 {{use of undeclared identifier 'dr2640_a🪷'}}
+// expected-error at -3 {{extraneous ')' before ';'}}
 }
 
-  // dr2642: na
+// dr2642: na
 
 namespace dr2644 { // dr2644: 8
-
-auto z = [a = 42](int a) { // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}} \
-                           // expected-note {{variable 'a' is explicitly captured here}}
+#if __cplusplus >= 201103L
+auto z = [a = 42](int a) {
+// cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
+// since-cxx11-error at -2 {{a lambda parameter cannot shadow an explicitly captured entity}}
+//   since-cxx11-note at -3 {{variable 'a' is explicitly captured here}}
      return 1;
 };
-
+#endif
 }
 
 #if __cplusplus >= 202302L
 namespace dr2650 { // dr2650: 17
 template <class T, T> struct S {};
-template <class T> int f(S<T, T{}>*); // expected-note {{type 'X' of non-type template parameter is not a structural type}}
+template <class T> int f(S<T, T{}>*); // #dr2650-f
 class X {
   int m;
 };
-int i0 = f<X>(0);   //expected-error {{no matching function for call to 'f'}}
+int i0 = f<X>(0);
+// since-cxx23-error at -1 {{no matching function for call to 'f'}}
+//   since-cxx23-note@#dr2650-f {{type 'X' of non-type template parameter is not a structural type}}
 }
 #endif
 
 #if __cplusplus >= 202302L
 namespace dr2653 { // dr2653: 18
   struct Test { void f(this const auto& = Test{}); };
-  // expected-error at -1 {{the explicit object parameter cannot have a default argument}}
+  // since-cxx23-error at -1 {{the explicit object parameter cannot have a default argument}}
   auto L = [](this const auto& = Test{}){};
-  // expected-error at -1 {{the explicit object parameter cannot have a default argument}}
+  // since-cxx23-error at -1 {{the explicit object parameter cannot have a default argument}}
 }
 #endif
 
@@ -141,6 +168,7 @@ void f() {
 }
 
 namespace dr2681 { // dr2681: 17
+#if __cplusplus >= 202002L
 using size_t = decltype(sizeof(int));
 
 template<class T, size_t N>
@@ -152,7 +180,7 @@ struct I {
   volatile T array[N];
 };
 template<size_t N>
-struct J {  // expected-note 3{{candidate}}
+struct J { // #dr2681-J
   unsigned char array[N];
 };
 
@@ -161,15 +189,24 @@ I i = { "def" };
 static_assert(__is_same(decltype(h), H<char, 4>));  // Not H<const char, 4>
 static_assert(__is_same(decltype(i), I<char, 4>));
 
-J j = { "ghi" };  // expected-error {{no viable constructor or deduction guide}}
+J j = { "ghi" };
+// since-cxx20-error at -1 {{no viable constructor or deduction guide}}
+//   since-cxx20-note@#dr2681-J {{candidate template ignored: could not match 'J<N>' against 'const char *'}}
+//   since-cxx20-note@#dr2681-J {{candidate template ignored: could not match 'const unsigned char' against 'const char'}}
+//   since-cxx20-note@#dr2681-J {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
+#endif
 }
 
 namespace dr2672 { // dr2672: 18 open
+#if __cplusplus >= 202002L
 template <class T>
-void f(T) requires requires { []() { T::invalid; } (); }; // expected-error{{type 'int' cannot be used prior to '::'}}
-                                                          // expected-note at -1{{while substituting into a lambda expression here}}
-                                                          // expected-note at -2{{in instantiation of requirement here}}
-                                                          // expected-note at -3{{while substituting template arguments into constraint expression here}}
+void f(T) requires requires { []() { T::invalid; } (); };
+// since-cxx20-error at -1 {{type 'int' cannot be used prior to '::' because it has no members}}
+//   since-cxx20-note at -2 {{while substituting into a lambda expression here}}
+//   since-cxx20-note at -3 {{in instantiation of requirement here}}
+//   since-cxx20-note at -4 {{while substituting template arguments into constraint expression here}}
+//   since-cxx20-note@#dr2672-f-0 {{while checking constraint satisfaction for template 'f<int>' required here}}
+//   since-cxx20-note@#dr2672-f-0 {{in instantiation of function template specialization 'dr2672::f<int>' requested here}}
 void f(...);
 
 template <class T>
@@ -179,11 +216,12 @@ void bar(T) requires requires {
 void bar(...);
 
 void m() {
-  f(0); // expected-note {{while checking constraint satisfaction for template 'f<int>' required here}}
-        // expected-note at -1 {{in instantiation of function template specialization}}
+  f(0); // #dr2672-f-0
   bar(0);
 }
+#endif
 }
+
 #if __cplusplus >= 202302L
 namespace dr2687 { // dr2687: 18
 struct S{
@@ -193,7 +231,8 @@ struct S{
 };
 
 void test() {
-    (&S::f)(1); // expected-error {{called object type 'void (dr2687::S::*)(int)' is not a function or function pointer}}
+    (&S::f)(1);
+    // since-cxx23-error at -1 {{called object type 'void (dr2687::S::*)(int)' is not a function or function pointer}}
     (&S::g)(1);
     (&S::h)(S(), 1);
 }
diff --git a/clang/test/CXX/drs/dr27xx.cpp b/clang/test/CXX/drs/dr27xx.cpp
index 5c7ce98f878da6..4f7d0d6b44a83e 100644
--- a/clang/test/CXX/drs/dr27xx.cpp
+++ b/clang/test/CXX/drs/dr27xx.cpp
@@ -1,6 +1,17 @@
-// RUN: %clang_cc1 -std=c++2c -verify %s
+// RUN: %clang_cc1 -std=c++98 -verify=expected %s
+// RUN: %clang_cc1 -std=c++11 -verify=expected %s
+// RUN: %clang_cc1 -std=c++14 -verify=expected %s
+// RUN: %clang_cc1 -std=c++17 -verify=expected %s
+// RUN: %clang_cc1 -std=c++20 -verify=expected %s
+// RUN: %clang_cc1 -std=c++23 -verify=expected,since-cxx23 %s
+// RUN: %clang_cc1 -std=c++2c -verify=expected,since-cxx23,since-cxx26 %s
+
+#if __cplusplus <= 202002L
+// expected-no-diagnostics
+#endif
 
 namespace dr2789 { // dr2789: 18 open
+#if __cplusplus >= 202302L
 template <typename T = int>
 struct Base {
     constexpr void g(); // #dr2789-g1
@@ -23,11 +34,12 @@ struct S : Base<T>, Base2<T> {
 void test() {
     S<> s;
     s.f();
-    s.g(); // expected-error {{call to member function 'g' is ambiguous}}
-           // expected-note@#dr2789-g1 {{candidate function}}
-           // expected-note@#dr2789-g2 {{candidate function}}
+    s.g();
+    // since-cxx23-error at -1 {{call to member function 'g' is ambiguous}}
+    //   since-cxx23-note@#dr2789-g1 {{candidate function}}
+    //   since-cxx23-note@#dr2789-g2 {{candidate function}}
 }
-
+#endif
 }
 
 namespace dr2798 { // dr2798: 17 drafting
@@ -49,7 +61,8 @@ struct X {
 };
 consteval X f() { return {}; }
 
-static_assert(false, f().s); // expected-error {{static assertion failed: Hello}}
+static_assert(false, f().s);
+// since-cxx26-error at -1 {{static assertion failed: Hello}}
 #endif
 } // namespace dr2798
 



More information about the cfe-commits mailing list