Skip to content

Commit 6434dce

Browse files
authored
[Clang][Interp] Fix the location of uninitialized base warning (llvm#100761)
Fix the location of `diag::note_constexpr_uninitialized_base`, make it same as current interpreter. This PR does not print type name with namespacethat was used to improve the current interpreter's type dump of base class type. --------- Signed-off-by: yronglin <yronglin777@gmail.com>
1 parent f395d82 commit 6434dce

File tree

6 files changed

+25
-25
lines changed

6 files changed

+25
-25
lines changed

clang/lib/AST/Interp/EvaluationResult.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
#include "InterpState.h"
1111
#include "Record.h"
1212
#include "clang/AST/ExprCXX.h"
13+
#include "llvm/ADT/STLExtras.h"
1314
#include "llvm/ADT/SetVector.h"
15+
#include <iterator>
1416

1517
namespace clang {
1618
namespace interp {
@@ -122,19 +124,18 @@ static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc,
122124
}
123125

124126
// Check Fields in all bases
125-
for (const Record::Base &B : R->bases()) {
127+
for (auto [I, B] : llvm::enumerate(R->bases())) {
126128
Pointer P = BasePtr.atField(B.Offset);
127129
if (!P.isInitialized()) {
128130
const Descriptor *Desc = BasePtr.getDeclDesc();
129-
if (Desc->asDecl())
130-
S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
131-
diag::note_constexpr_uninitialized_base)
131+
if (const auto *CD = dyn_cast_if_present<CXXRecordDecl>(R->getDecl())) {
132+
const auto &BS = *std::next(CD->bases_begin(), I);
133+
S.FFDiag(BS.getBaseTypeLoc(), diag::note_constexpr_uninitialized_base)
134+
<< B.Desc->getType() << BS.getSourceRange();
135+
} else {
136+
S.FFDiag(Desc->getLocation(), diag::note_constexpr_uninitialized_base)
132137
<< B.Desc->getType();
133-
else
134-
S.FFDiag(BasePtr.getDeclDesc()->asExpr()->getExprLoc(),
135-
diag::note_constexpr_uninitialized_base)
136-
<< B.Desc->getType();
137-
138+
}
138139
return false;
139140
}
140141
Result &= CheckFieldsInitialized(S, Loc, P, B.R);

clang/test/AST/Interp/constexpr-subobj-initialization.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,36 @@
55
/// Differences:
66
/// 1) The type of the uninitialized base class is printed WITH the namespace,
77
/// i.e. 'baseclass_uninit::DelBase' instead of just 'DelBase'.
8-
/// 2) The location is not the base specifier declaration, but the call site
9-
/// of the constructor.
108

119

1210
namespace baseclass_uninit {
1311
struct DelBase {
1412
constexpr DelBase() = delete; // expected-note {{'DelBase' has been explicitly marked deleted here}}
1513
};
1614

17-
struct Foo : DelBase {
15+
struct Foo : DelBase { // expected-note 2{{constructor of base class 'baseclass_uninit::DelBase' is not called}}
1816
constexpr Foo() {}; // expected-error {{call to deleted constructor of 'DelBase'}}
1917
};
20-
constexpr Foo f; // expected-error {{must be initialized by a constant expression}} \
21-
// expected-note {{constructor of base class 'baseclass_uninit::DelBase' is not called}}
18+
constexpr Foo f; // expected-error {{must be initialized by a constant expression}}
2219

2320
struct Bar : Foo {
2421
constexpr Bar() {};
2522
};
26-
constexpr Bar bar; // expected-error {{must be initialized by a constant expression}} \
27-
// expected-note {{constructor of base class 'baseclass_uninit::DelBase' is not called}}
23+
constexpr Bar bar; // expected-error {{must be initialized by a constant expression}}
2824

2925
struct Base {};
30-
struct A : Base {
26+
struct A : Base { // expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}}
3127
constexpr A() : value() {} // expected-error {{member initializer 'value' does not name a non-static data member or base class}}
3228
};
3329

34-
constexpr A a; // expected-error {{must be initialized by a constant expression}} \
35-
// expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}}
30+
constexpr A a; // expected-error {{must be initialized by a constant expression}}
3631

3732

38-
struct B : Base {
33+
struct B : Base { // expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}}
3934
constexpr B() : {} // expected-error {{expected class member or base class name}}
4035
};
4136

42-
constexpr B b; // expected-error {{must be initialized by a constant expression}} \
43-
// expected-note {{constructor of base class 'baseclass_uninit::Base' is not called}}
37+
constexpr B b; // expected-error {{must be initialized by a constant expression}}
4438
} // namespace baseclass_uninit
4539

4640

clang/test/C/C23/n3018.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion %s
2+
// RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -fexperimental-new-constant-interpreter %s
23

34
/* WG14 N3018: Full
45
* The constexpr specifier for object definitions

clang/test/CodeGen/pr3518.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
2+
// RUN: %clang_cc1 %s -fexperimental-new-constant-interpreter -emit-llvm -o - | FileCheck %s
23
// PR 3518
34
// Some of the objects were coming out as uninitialized (external) before 3518
45
// was fixed. Internal names are different between llvm-gcc and clang so they

clang/test/Preprocessor/embed_weird.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
// RUN: printf "\0" > %t/null_byte.bin
55
// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions
66
// RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only --embed-dir=%t -verify=expected,c
7+
// RUN: %clang_cc1 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions
8+
// RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,c
79
#embed <media/empty>
810
;
911

clang/test/SemaCXX/constexpr-subobj-initialization.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
23

34
namespace baseclass_uninit {
45
struct DelBase {
56
constexpr DelBase() = delete; // expected-note {{'DelBase' has been explicitly marked deleted here}}
67
};
78

8-
struct Foo : DelBase { // expected-note 2{{constructor of base class 'DelBase' is not called}}
9+
struct Foo : DelBase { // expected-note-re 2{{constructor of base class '{{.*}}DelBase' is not called}}
910
constexpr Foo() {}; // expected-error {{call to deleted constructor of 'DelBase'}}
1011
};
1112
constexpr Foo f; // expected-error {{must be initialized by a constant expression}}
@@ -15,13 +16,13 @@ struct Bar : Foo {
1516
constexpr Bar bar; // expected-error {{must be initialized by a constant expression}}
1617

1718
struct Base {};
18-
struct A : Base { // expected-note {{constructor of base class 'Base' is not called}}
19+
struct A : Base { // expected-note-re {{constructor of base class '{{.*}}Base' is not called}}
1920
constexpr A() : value() {} // expected-error {{member initializer 'value' does not name a non-static data member or base class}}
2021
};
2122

2223
constexpr A a; // expected-error {{must be initialized by a constant expression}}
2324

24-
struct B : Base { // expected-note {{constructor of base class 'Base' is not called}}
25+
struct B : Base { // expected-note-re {{constructor of base class '{{.*}}Base' is not called}}
2526
constexpr B() : {} // expected-error {{expected class member or base class name}}
2627
};
2728

0 commit comments

Comments
 (0)