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/8] [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/8] 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/8] 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/8] 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/8] 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/8] [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(); >From dc18559f01084b55707ed47e533e1fdb340131ac Mon Sep 17 00:00:00 2001 From: yronglin <yronglin...@gmail.com> Date: Wed, 31 Jul 2024 00:42:05 +0800 Subject: [PATCH 7/8] Address review comments Signed-off-by: yronglin <yronglin...@gmail.com> --- clang/lib/AST/Interp/EvaluationResult.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index e9e0d4afb2a5b..469b28434b3b7 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -12,6 +12,7 @@ #include "clang/AST/ExprCXX.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" +#include "llvm/Support/Casting.h" #include <iterator> namespace clang { @@ -128,15 +129,12 @@ static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc, Pointer P = BasePtr.atField(B.Offset); if (!P.isInitialized()) { const Descriptor *Desc = BasePtr.getDeclDesc(); - if (const auto *CD = dyn_cast_or_null<CXXRecordDecl>(R->getDecl())) { + if (const auto *CD = dyn_cast_if_present<CXXRecordDecl>(R->getDecl())) { const auto &BS = *std::next(CD->bases_begin(), 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) + S.FFDiag(Desc->getLocation(), diag::note_constexpr_uninitialized_base) << B.Desc->getType(); } return false; >From c3736da5bb71a500ff1fd75a6c84f47806181e5b Mon Sep 17 00:00:00 2001 From: yronglin <yronglin...@gmail.com> Date: Wed, 31 Jul 2024 00:43:51 +0800 Subject: [PATCH 8/8] Remove include Signed-off-by: yronglin <yronglin...@gmail.com> --- clang/lib/AST/Interp/EvaluationResult.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 469b28434b3b7..bdebd19af9f94 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -12,7 +12,6 @@ #include "clang/AST/ExprCXX.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" -#include "llvm/Support/Casting.h" #include <iterator> namespace clang { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits