https://github.com/yronglin updated 
https://github.com/llvm/llvm-project/pull/100761

>From eb237d1b6434c16366f8095f47af1456cb776a27 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Fri, 26 Jul 2024 23:09:42 +0800
Subject: [PATCH 1/6] [Clang][Interp] Fix the location of uninitialized base
 warning

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/lib/AST/Interp/EvaluationResult.cpp     | 20 +++++++++----------
 .../constexpr-subobj-initialization.cpp       | 18 +++++++----------
 .../constexpr-subobj-initialization.cpp       |  7 ++++---
 3 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp 
b/clang/lib/AST/Interp/EvaluationResult.cpp
index 1b255711c7b36..57e12598d12e4 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -122,22 +122,20 @@ static bool CheckFieldsInitialized(InterpState &S, 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base &B : R->bases()) {
+  unsigned BaseIndex = 0;
+  const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(R->getDecl());
+  for (const CXXBaseSpecifier &BS : CD->bases()) {
+    const Record::Base &B = *R->getBase(BaseIndex);
     Pointer P = BasePtr.atField(B.Offset);
     if (!P.isInitialized()) {
-      const Descriptor *Desc = BasePtr.getDeclDesc();
-      if (Desc->asDecl())
-        S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
-                 diag::note_constexpr_uninitialized_base)
-            << B.Desc->getType();
-      else
-        S.FFDiag(BasePtr.getDeclDesc()->asExpr()->getExprLoc(),
-                 diag::note_constexpr_uninitialized_base)
-            << B.Desc->getType();
-
+      SourceLocation TypeBeginLoc = BS.getBaseTypeLoc();
+      SourceRange Range(TypeBeginLoc, BS.getEndLoc());
+      S.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
+          << B.Desc->getType() << Range;
       return false;
     }
     Result &= CheckFieldsInitialized(S, Loc, P, B.R);
+    BaseIndex++;
   }
 
   // TODO: Virtual bases
diff --git a/clang/test/AST/Interp/constexpr-subobj-initialization.cpp 
b/clang/test/AST/Interp/constexpr-subobj-initialization.cpp
index 4976b165468bd..4c067423aedfd 100644
--- a/clang/test/AST/Interp/constexpr-subobj-initialization.cpp
+++ b/clang/test/AST/Interp/constexpr-subobj-initialization.cpp
@@ -14,33 +14,29 @@ struct DelBase {
   constexpr DelBase() = delete; // expected-note {{'DelBase' has been 
explicitly marked deleted here}}
 };
 
-struct Foo : DelBase {
+struct Foo : DelBase { // expected-note 2{{constructor of base class 
'baseclass_uninit::DelBase' is not called}}
   constexpr Foo() {}; // expected-error {{call to deleted constructor of 
'DelBase'}}
 };
-constexpr Foo f; // expected-error {{must be initialized by a constant 
expression}} \
-                 // expected-note {{constructor of base class 
'baseclass_uninit::DelBase' is not called}}
+constexpr Foo f; // expected-error {{must be initialized by a constant 
expression}}
 
 struct Bar : Foo {
   constexpr Bar() {};
 };
-constexpr Bar bar; // expected-error {{must be initialized by a constant 
expression}} \
-                   // expected-note {{constructor of base class 
'baseclass_uninit::DelBase' is not called}}
+constexpr Bar bar; // expected-error {{must be initialized by a constant 
expression}}
 
 struct Base {};
-struct A : Base {
+struct A : Base { // expected-note {{constructor of base class 
'baseclass_uninit::Base' is not called}}
   constexpr A() : value() {} // expected-error {{member initializer 'value' 
does not name a non-static data member or base class}}
 };
 
-constexpr A a; // expected-error {{must be initialized by a constant 
expression}} \
-               // expected-note {{constructor of base class 
'baseclass_uninit::Base' is not called}}
+constexpr A a; // expected-error {{must be initialized by a constant 
expression}}
 
 
-struct B : Base {
+struct B : Base { // expected-note {{constructor of base class 
'baseclass_uninit::Base' is not called}}
   constexpr B() : {} // expected-error {{expected class member or base class 
name}}
 };
 
-constexpr B b; // expected-error {{must be initialized by a constant 
expression}} \
-               // expected-note {{constructor of base class 
'baseclass_uninit::Base' is not called}}
+constexpr B b; // expected-error {{must be initialized by a constant 
expression}}
 } // namespace baseclass_uninit
 
 
diff --git a/clang/test/SemaCXX/constexpr-subobj-initialization.cpp 
b/clang/test/SemaCXX/constexpr-subobj-initialization.cpp
index cd096a9270937..f0252df1e2ce1 100644
--- a/clang/test/SemaCXX/constexpr-subobj-initialization.cpp
+++ b/clang/test/SemaCXX/constexpr-subobj-initialization.cpp
@@ -1,11 +1,12 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify 
-fexperimental-new-constant-interpreter %s
 
 namespace baseclass_uninit {
 struct DelBase {
   constexpr DelBase() = delete; // expected-note {{'DelBase' has been 
explicitly marked deleted here}}
 };
 
-struct Foo : DelBase {  // expected-note 2{{constructor of base class 
'DelBase' is not called}}
+struct Foo : DelBase {  // expected-note-re 2{{constructor of base class 
'{{.*}}DelBase' is not called}}
   constexpr Foo() {}; // expected-error {{call to deleted constructor of 
'DelBase'}}
 };
 constexpr Foo f; // expected-error {{must be initialized by a constant 
expression}}
@@ -15,13 +16,13 @@ struct Bar : Foo {
 constexpr Bar bar; // expected-error {{must be initialized by a constant 
expression}}
 
 struct Base {};
-struct A : Base { // expected-note {{constructor of base class 'Base' is not 
called}}
+struct A : Base { // expected-note-re {{constructor of base class '{{.*}}Base' 
is not called}}
   constexpr A() : value() {} // expected-error {{member initializer 'value' 
does not name a non-static data member or base class}}
 };
 
 constexpr A a; // expected-error {{must be initialized by a constant 
expression}}
 
-struct B : Base { // expected-note {{constructor of base class 'Base' is not 
called}}
+struct B : Base { // expected-note-re {{constructor of base class '{{.*}}Base' 
is not called}}
   constexpr B() : {} // expected-error {{expected class member or base class 
name}}
 };
 

>From a15fa5c8a0ed09549aa9a32a76a89c5cf78969bb Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Sat, 27 Jul 2024 23:55:02 +0800
Subject: [PATCH 2/6] Address review comments and enable new interpreter in
 more test

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/include/clang/AST/DeclCXX.h             | 10 ++++++++
 clang/lib/AST/Interp/EvaluationResult.cpp     | 24 ++++++++++++-------
 .../constexpr-subobj-initialization.cpp       |  2 --
 clang/test/C/C23/n3018.c                      |  1 +
 clang/test/CodeGen/pr3518.c                   |  1 +
 clang/test/Preprocessor/embed_weird.cpp       |  2 ++
 6 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index fb52ac804849d..3567a892a93d8 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -612,6 +612,11 @@ class CXXRecordDecl : public RecordDecl {
   /// Retrieves the number of base classes of this class.
   unsigned getNumBases() const { return data().NumBases; }
 
+  const CXXBaseSpecifier &getBase(unsigned Index) const {
+    assert(Index < getNumBases() && "Base access out of range!");
+    return data().getBases()[Index];
+  }
+
   using base_class_range = llvm::iterator_range<base_class_iterator>;
   using base_class_const_range =
       llvm::iterator_range<base_class_const_iterator>;
@@ -633,6 +638,11 @@ class CXXRecordDecl : public RecordDecl {
   /// Retrieves the number of virtual base classes of this class.
   unsigned getNumVBases() const { return data().NumVBases; }
 
+  const CXXBaseSpecifier &getVBase(unsigned Index) const {
+    assert(Index < getNumBases() && "Virtual base access out of range!");
+    return data().getVBases()[Index];
+  }
+
   base_class_range vbases() {
     return base_class_range(vbases_begin(), vbases_end());
   }
diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp 
b/clang/lib/AST/Interp/EvaluationResult.cpp
index 57e12598d12e4..6dc72448faa87 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -10,6 +10,7 @@
 #include "InterpState.h"
 #include "Record.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/SetVector.h"
 
 namespace clang {
@@ -122,20 +123,25 @@ static bool CheckFieldsInitialized(InterpState &S, 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  unsigned BaseIndex = 0;
-  const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(R->getDecl());
-  for (const CXXBaseSpecifier &BS : CD->bases()) {
-    const Record::Base &B = *R->getBase(BaseIndex);
+  for (unsigned I = 0, E = R->getNumBases(); I != E; ++I) {
+    const auto &B = *R->getBase(I);
     Pointer P = BasePtr.atField(B.Offset);
     if (!P.isInitialized()) {
-      SourceLocation TypeBeginLoc = BS.getBaseTypeLoc();
-      SourceRange Range(TypeBeginLoc, BS.getEndLoc());
-      S.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
-          << B.Desc->getType() << Range;
+      const Descriptor *Desc = BasePtr.getDeclDesc();
+      if (const auto *CD = dyn_cast_or_null<CXXRecordDecl>(R->getDecl())) {
+        const auto &BS = CD->getBase(I);
+        S.FFDiag(BS.getBaseTypeLoc(), diag::note_constexpr_uninitialized_base)
+            << B.Desc->getType() << BS.getSourceRange();
+      } else {
+        SourceLocation Loc =
+            Desc->asDecl() ? BasePtr.getDeclDesc()->asDecl()->getLocation()
+                           : BasePtr.getDeclDesc()->asExpr()->getExprLoc();
+        S.FFDiag(Loc, diag::note_constexpr_uninitialized_base)
+            << B.Desc->getType();
+      }
       return false;
     }
     Result &= CheckFieldsInitialized(S, Loc, P, B.R);
-    BaseIndex++;
   }
 
   // TODO: Virtual bases
diff --git a/clang/test/AST/Interp/constexpr-subobj-initialization.cpp 
b/clang/test/AST/Interp/constexpr-subobj-initialization.cpp
index 4c067423aedfd..1a35994944190 100644
--- a/clang/test/AST/Interp/constexpr-subobj-initialization.cpp
+++ b/clang/test/AST/Interp/constexpr-subobj-initialization.cpp
@@ -5,8 +5,6 @@
 /// Differences:
 ///   1) The type of the uninitialized base class is printed WITH the 
namespace,
 ///      i.e. 'baseclass_uninit::DelBase' instead of just 'DelBase'.
-///   2) The location is not the base specifier declaration, but the call site
-///      of the constructor.
 
 
 namespace baseclass_uninit {
diff --git a/clang/test/C/C23/n3018.c b/clang/test/C/C23/n3018.c
index 0d54d53b7499f..4ad2fffbfde80 100644
--- a/clang/test/C/C23/n3018.c
+++ b/clang/test/C/C23/n3018.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion 
-Wno-constant-conversion %s
+// RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion 
-Wno-constant-conversion -fexperimental-new-constant-interpreter %s
 
 /* WG14 N3018: Full
  * The constexpr specifier for object definitions
diff --git a/clang/test/CodeGen/pr3518.c b/clang/test/CodeGen/pr3518.c
index f888add986258..a3cd866e92201 100644
--- a/clang/test/CodeGen/pr3518.c
+++ b/clang/test/CodeGen/pr3518.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fexperimental-new-constant-interpreter -emit-llvm -o - 
| FileCheck %s
 // PR 3518
 // Some of the objects were coming out as uninitialized (external) before 3518
 // was fixed.  Internal names are different between llvm-gcc and clang so they
diff --git a/clang/test/Preprocessor/embed_weird.cpp 
b/clang/test/Preprocessor/embed_weird.cpp
index 90180e2d3cc70..9a984e40d4aa2 100644
--- a/clang/test/Preprocessor/embed_weird.cpp
+++ b/clang/test/Preprocessor/embed_weird.cpp
@@ -4,6 +4,8 @@
 // RUN: printf "\0" > %t/null_byte.bin
 // RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%t -verify=expected,cxx 
-Wno-c23-extensions
 // RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only --embed-dir=%t 
-verify=expected,c
+// RUN: %clang_cc1 %s -fsyntax-only -fexperimental-new-constant-interpreter 
--embed-dir=%t -verify=expected,cxx -Wno-c23-extensions
+// RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only 
-fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,c
 #embed <media/empty>
 ;
 

>From 63eccaec6b77987206ce620827bbeb4e54f72d26 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Mon, 29 Jul 2024 22:01:35 +0800
Subject: [PATCH 3/6] Fix getVBase

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/include/clang/AST/DeclCXX.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 3567a892a93d8..6a99f511fd0a3 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -639,7 +639,7 @@ class CXXRecordDecl : public RecordDecl {
   unsigned getNumVBases() const { return data().NumVBases; }
 
   const CXXBaseSpecifier &getVBase(unsigned Index) const {
-    assert(Index < getNumBases() && "Virtual base access out of range!");
+    assert(Index < getNumVBases() && "Virtual base access out of range!");
     return data().getVBases()[Index];
   }
 

>From 91a40f9efa526dc371e7b36e8d332125a1840aad Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Tue, 30 Jul 2024 13:10:23 +0800
Subject: [PATCH 4/6] Remove getBase/getVBase in CXXRecordDecl

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/include/clang/AST/DeclCXX.h         | 10 ----------
 clang/lib/AST/Interp/EvaluationResult.cpp |  4 +++-
 2 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 6a99f511fd0a3..fb52ac804849d 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -612,11 +612,6 @@ class CXXRecordDecl : public RecordDecl {
   /// Retrieves the number of base classes of this class.
   unsigned getNumBases() const { return data().NumBases; }
 
-  const CXXBaseSpecifier &getBase(unsigned Index) const {
-    assert(Index < getNumBases() && "Base access out of range!");
-    return data().getBases()[Index];
-  }
-
   using base_class_range = llvm::iterator_range<base_class_iterator>;
   using base_class_const_range =
       llvm::iterator_range<base_class_const_iterator>;
@@ -638,11 +633,6 @@ class CXXRecordDecl : public RecordDecl {
   /// Retrieves the number of virtual base classes of this class.
   unsigned getNumVBases() const { return data().NumVBases; }
 
-  const CXXBaseSpecifier &getVBase(unsigned Index) const {
-    assert(Index < getNumVBases() && "Virtual base access out of range!");
-    return data().getVBases()[Index];
-  }
-
   base_class_range vbases() {
     return base_class_range(vbases_begin(), vbases_end());
   }
diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp 
b/clang/lib/AST/Interp/EvaluationResult.cpp
index 6dc72448faa87..1f2be71f7eab0 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -11,7 +11,9 @@
 #include "Record.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include <iterator>
 
 namespace clang {
 namespace interp {
@@ -129,7 +131,7 @@ static bool CheckFieldsInitialized(InterpState &S, 
SourceLocation Loc,
     if (!P.isInitialized()) {
       const Descriptor *Desc = BasePtr.getDeclDesc();
       if (const auto *CD = dyn_cast_or_null<CXXRecordDecl>(R->getDecl())) {
-        const auto &BS = CD->getBase(I);
+        const auto &BS = *std::next(CD->bases_begin(), I);
         S.FFDiag(BS.getBaseTypeLoc(), diag::note_constexpr_uninitialized_base)
             << B.Desc->getType() << BS.getSourceRange();
       } else {

>From 7a171ef3542e3fc42f3cf626b0029d399e50cdb5 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Tue, 30 Jul 2024 13:12:01 +0800
Subject: [PATCH 5/6] Remove unused include

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/lib/AST/Interp/EvaluationResult.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp 
b/clang/lib/AST/Interp/EvaluationResult.cpp
index 1f2be71f7eab0..0db68e9309bb2 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -10,8 +10,6 @@
 #include "InterpState.h"
 #include "Record.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include <iterator>
 

>From d10f52724dab17b28f1eda7da5769dbbd769d942 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Tue, 30 Jul 2024 23:03:32 +0800
Subject: [PATCH 6/6] [Clang] Use llvm::enumerate

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/lib/AST/Interp/EvaluationResult.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp 
b/clang/lib/AST/Interp/EvaluationResult.cpp
index 0db68e9309bb2..e9e0d4afb2a5b 100644
--- a/clang/lib/AST/Interp/EvaluationResult.cpp
+++ b/clang/lib/AST/Interp/EvaluationResult.cpp
@@ -10,6 +10,7 @@
 #include "InterpState.h"
 #include "Record.h"
 #include "clang/AST/ExprCXX.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include <iterator>
 
@@ -123,8 +124,7 @@ static bool CheckFieldsInitialized(InterpState &S, 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (unsigned I = 0, E = R->getNumBases(); I != E; ++I) {
-    const auto &B = *R->getBase(I);
+  for (auto [I, B] : llvm::enumerate(R->bases())) {
     Pointer P = BasePtr.atField(B.Offset);
     if (!P.isInitialized()) {
       const Descriptor *Desc = BasePtr.getDeclDesc();

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to