Skip to content

Commit 0befa62

Browse files
authored
Merge branch 'llvm:main' into main
2 parents 8bf781a + 195e640 commit 0befa62

File tree

30 files changed

+310
-125
lines changed

30 files changed

+310
-125
lines changed

clang-tools-extra/clang-tidy/concurrency/MtUnsafeCheck.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ static const clang::StringRef GlibcFunctions[] = {
153153
"::sigsuspend",
154154
"::sleep",
155155
"::srand48",
156-
"::strerror",
157156
"::strsignal",
158157
"::strtok",
159158
"::tcflow",

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ Changes in existing checks
172172
<clang-tidy/checks/cert/err33-c>` check by fixing false positives when
173173
a function name is just prefixed with a targeted function name.
174174

175+
- Improved :doc:`concurrency-mt-unsafe
176+
<clang-tidy/checks/concurrency/mt-unsafe>` check by fixing a false positive
177+
where ``strerror`` was flagged as MT-unsafe.
178+
175179
- Improved :doc:`misc-const-correctness
176180
<clang-tidy/checks/misc/const-correctness>` check by adding the option
177181
`AllowedTypes`, that excludes specified types from const-correctness

clang-tools-extra/test/clang-tidy/checkers/concurrency/mt-unsafe-glibc.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
extern unsigned int sleep (unsigned int __seconds);
44
extern int *gmtime (const int *__timer);
55
extern char *dirname (char *__path);
6+
extern char *strerror(int errnum);
67

78
void foo() {
89
sleep(2);
@@ -12,4 +13,6 @@ void foo() {
1213
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: function is not thread safe [concurrency-mt-unsafe]
1314

1415
dirname(nullptr);
16+
17+
strerror(0);
1518
}

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,8 @@ Bug Fixes to C++ Support
744744
- Fixed a function declaration mismatch that caused inconsistencies between concepts and variable template declarations. (#GH139476)
745745
- Clang no longer segfaults when there is a configuration mismatch between modules and their users (http://crbug.com/400353616).
746746
- Fix an incorrect deduction when calling an explicit object member function template through an overload set address.
747+
- Fixed bug in constant evaluation that would allow using the value of a
748+
reference in its own initializer in C++23 mode (#GH131330).
747749

748750
Bug Fixes to AST Handling
749751
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3492,11 +3492,33 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
34923492

34933493
APValue::LValueBase Base(VD, Frame ? Frame->Index : 0, Version);
34943494

3495+
auto CheckUninitReference = [&](bool IsLocalVariable) {
3496+
if (!Result->hasValue() && VD->getType()->isReferenceType()) {
3497+
// C++23 [expr.const]p8
3498+
// ... For such an object that is not usable in constant expressions, the
3499+
// dynamic type of the object is constexpr-unknown. For such a reference
3500+
// that is not usable in constant expressions, the reference is treated
3501+
// as binding to an unspecified object of the referenced type whose
3502+
// lifetime and that of all subobjects includes the entire constant
3503+
// evaluation and whose dynamic type is constexpr-unknown.
3504+
//
3505+
// Variables that are part of the current evaluation are not
3506+
// constexpr-unknown.
3507+
if (!AllowConstexprUnknown || IsLocalVariable) {
3508+
if (!Info.checkingPotentialConstantExpression())
3509+
Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3510+
return false;
3511+
}
3512+
Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD, Base);
3513+
}
3514+
return true;
3515+
};
3516+
34953517
// If this is a local variable, dig out its value.
34963518
if (Frame) {
34973519
Result = Frame->getTemporary(VD, Version);
34983520
if (Result)
3499-
return true;
3521+
return CheckUninitReference(/*IsLocalVariable=*/true);
35003522

35013523
if (!isa<ParmVarDecl>(VD)) {
35023524
// Assume variables referenced within a lambda's call operator that were
@@ -3521,7 +3543,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
35213543
// in-flight value.
35223544
if (Info.EvaluatingDecl == Base) {
35233545
Result = Info.EvaluatingDeclValue;
3524-
return true;
3546+
return CheckUninitReference(/*IsLocalVariable=*/false);
35253547
}
35263548

35273549
// P2280R4 struck the restriction that variable of reference type lifetime
@@ -3594,11 +3616,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
35943616
// type so we can no longer assume we have an Init.
35953617
// Used to be C++20 [expr.const]p5.12:
35963618
// ... reference has a preceding initialization and either ...
3597-
if (Init && !VD->evaluateValue()) {
3598-
if (AllowConstexprUnknown) {
3599-
Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD, Base);
3600-
return true;
3601-
}
3619+
if (Init && !VD->evaluateValue() && !AllowConstexprUnknown) {
36023620
Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
36033621
NoteLValueLocation(Info, Base);
36043622
return false;
@@ -3636,18 +3654,14 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
36363654

36373655
Result = VD->getEvaluatedValue();
36383656

3639-
// C++23 [expr.const]p8
3640-
// ... For such an object that is not usable in constant expressions, the
3641-
// dynamic type of the object is constexpr-unknown. For such a reference that
3642-
// is not usable in constant expressions, the reference is treated as binding
3643-
// to an unspecified object of the referenced type whose lifetime and that of
3644-
// all subobjects includes the entire constant evaluation and whose dynamic
3645-
// type is constexpr-unknown.
3646-
if (AllowConstexprUnknown) {
3647-
if (!Result)
3657+
if (!Result) {
3658+
if (AllowConstexprUnknown)
36483659
Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD, Base);
3660+
else
3661+
return false;
36493662
}
3650-
return true;
3663+
3664+
return CheckUninitReference(/*IsLocalVariable=*/false);
36513665
}
36523666

36533667
/// Get the base index of the given base class within an APValue representing
@@ -8953,12 +8967,7 @@ bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
89538967
return Error(E);
89548968
}
89558969

8956-
89578970
bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
8958-
// C++23 [expr.const]p8 If we have a reference type allow unknown references
8959-
// and pointers.
8960-
bool AllowConstexprUnknown =
8961-
Info.getLangOpts().CPlusPlus23 && VD->getType()->isReferenceType();
89628971
// If we are within a lambda's call operator, check whether the 'VD' referred
89638972
// to within 'E' actually represents a lambda-capture that maps to a
89648973
// data-member/field within the closure object, and if so, evaluate to the
@@ -9025,26 +9034,6 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
90259034
APValue *V;
90269035
if (!evaluateVarDeclInit(Info, E, VD, Frame, Version, V))
90279036
return false;
9028-
if (!V->hasValue()) {
9029-
// FIXME: Is it possible for V to be indeterminate here? If so, we should
9030-
// adjust the diagnostic to say that.
9031-
// C++23 [expr.const]p8 If we have a variable that is unknown reference
9032-
// or pointer it may not have a value but still be usable later on so do not
9033-
// diagnose.
9034-
if (!Info.checkingPotentialConstantExpression() && !AllowConstexprUnknown)
9035-
Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
9036-
9037-
// C++23 [expr.const]p8 If we have a variable that is unknown reference or
9038-
// pointer try to recover it from the frame and set the result accordingly.
9039-
if (VD->getType()->isReferenceType() && AllowConstexprUnknown) {
9040-
if (Frame) {
9041-
Result.set({VD, Frame->Index, Version});
9042-
return true;
9043-
}
9044-
return Success(VD);
9045-
}
9046-
return false;
9047-
}
90489037

90499038
return Success(*V, E);
90509039
}

clang/test/Modules/fmodules-validate-once-per-build-session.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060

6161
// ===
6262
// Change the sources.
63+
// RUN: sleep 1
6364
// RUN: echo 'void meow2(void);' > %t/Inputs/foo.h
6465
// RUN: echo 'module Bar { header "bar.h" export * }' > %t/Inputs/bar.modulemap
6566

@@ -95,7 +96,7 @@
9596
// ===
9697
// Recompile the module if the today's date is before 01 January 2100.
9798
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
98-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fno-modules-force-validate-user-headers -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
99+
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
99100
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user-no-force -fsyntax-only -I %t/Inputs -fno-modules-force-validate-user-headers -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
100101
// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
101102
// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp

clang/test/SemaCXX/constant-expression-p2280r4.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -std=c++23 -verify %s
1+
// RUN: %clang_cc1 -std=c++23 -verify=expected,nointerpreter %s
22
// RUN: %clang_cc1 -std=c++23 -verify=expected,interpreter %s -fexperimental-new-constant-interpreter
33

44
using size_t = decltype(sizeof(0));
@@ -199,3 +199,54 @@ int f() {
199199
return !get_value<Dummy>(); // contextually convert the function call result to bool
200200
}
201201
}
202+
203+
namespace uninit_reference_used {
204+
int y;
205+
constexpr int &r = r; // expected-error {{must be initialized by a constant expression}} \
206+
// expected-note {{initializer of 'r' is not a constant expression}} \
207+
// expected-note {{declared here}}
208+
constexpr int &rr = (rr, y);
209+
constexpr int &g() {
210+
int &x = x; // expected-warning {{reference 'x' is not yet bound to a value when used within its own initialization}} \
211+
// nointerpreter-note {{use of reference outside its lifetime is not allowed in a constant expression}} \
212+
// interpreter-note {{read of uninitialized object is not allowed in a constant expression}}
213+
return x;
214+
}
215+
constexpr int &gg = g(); // expected-error {{must be initialized by a constant expression}} \
216+
// expected-note {{in call to 'g()'}}
217+
constexpr int g2() {
218+
int &x = x; // expected-warning {{reference 'x' is not yet bound to a value when used within its own initialization}} \
219+
// nointerpreter-note {{use of reference outside its lifetime is not allowed in a constant expression}} \
220+
// interpreter-note {{read of uninitialized object is not allowed in a constant expression}}
221+
return x;
222+
}
223+
constexpr int gg2 = g2(); // expected-error {{must be initialized by a constant expression}} \
224+
// expected-note {{in call to 'g2()'}}
225+
constexpr int &g3() {
226+
int &x = (x,y); // expected-warning{{left operand of comma operator has no effect}} \
227+
// expected-warning {{reference 'x' is not yet bound to a value when used within its own initialization}} \
228+
// nointerpreter-note {{use of reference outside its lifetime is not allowed in a constant expression}}
229+
return x;
230+
}
231+
constexpr int &gg3 = g3(); // nointerpreter-error {{must be initialized by a constant expression}} \
232+
// nointerpreter-note {{in call to 'g3()'}}
233+
typedef decltype(sizeof(1)) uintptr_t;
234+
constexpr uintptr_t g4() {
235+
uintptr_t * &x = x; // expected-warning {{reference 'x' is not yet bound to a value when used within its own initialization}} \
236+
// nointerpreter-note {{use of reference outside its lifetime is not allowed in a constant expression}} \
237+
// interpreter-note {{read of uninitialized object is not allowed in a constant expression}}
238+
*(uintptr_t*)x = 10;
239+
return 3;
240+
}
241+
constexpr uintptr_t gg4 = g4(); // expected-error {{must be initialized by a constant expression}} \
242+
// expected-note {{in call to 'g4()'}}
243+
constexpr int g5() {
244+
int &x = x; // expected-warning {{reference 'x' is not yet bound to a value when used within its own initialization}} \
245+
// nointerpreter-note {{use of reference outside its lifetime is not allowed in a constant expression}} \
246+
// interpreter-note {{read of uninitialized object is not allowed in a constant expression}}
247+
return 3;
248+
}
249+
constexpr uintptr_t gg5 = g5(); // expected-error {{must be initialized by a constant expression}} \
250+
// expected-note {{in call to 'g5()'}}
251+
252+
}

clang/utils/TableGen/ClangOptionDocEmitter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
367367
R->getValueAsListOfDefs("HelpTextsForVariants")) {
368368
// This is a list of visibilities.
369369
ArrayRef<const Init *> Visibilities =
370-
VisibilityHelp->getValueAsListInit("Visibilities")->getValues();
370+
VisibilityHelp->getValueAsListInit("Visibilities")->getElements();
371371

372372
// See if any of the program's visibilities are in the list.
373373
for (StringRef DocInfoMask :

clang/utils/TableGen/NeonEmitter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ class Intrinsic {
486486
return Idx;
487487
}
488488

489-
bool hasBody() const { return Body && !Body->getValues().empty(); }
489+
bool hasBody() const { return Body && !Body->empty(); }
490490

491491
void setNeededEarly() { NeededEarly = true; }
492492

@@ -1436,14 +1436,14 @@ void Intrinsic::emitBodyAsBuiltinCall() {
14361436
void Intrinsic::emitBody(StringRef CallPrefix) {
14371437
std::vector<std::string> Lines;
14381438

1439-
if (!Body || Body->getValues().empty()) {
1439+
if (!Body || Body->empty()) {
14401440
// Nothing specific to output - must output a builtin.
14411441
emitBodyAsBuiltinCall();
14421442
return;
14431443
}
14441444

14451445
// We have a list of "things to output". The last should be returned.
1446-
for (auto *I : Body->getValues()) {
1446+
for (auto *I : Body->getElements()) {
14471447
if (const auto *SI = dyn_cast<StringInit>(I)) {
14481448
Lines.push_back(replaceParamsIn(SI->getAsString()));
14491449
} else if (const auto *DI = dyn_cast<DagInit>(I)) {

lldb/unittests/DAP/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ add_lldb_unittest(DAPTests
22
DAPTest.cpp
33
FifoFilesTest.cpp
44
Handler/DisconnectTest.cpp
5+
Handler/ContinueTest.cpp
56
JSONUtilsTest.cpp
67
LLDBUtilsTest.cpp
78
ProtocolTypesTest.cpp

0 commit comments

Comments
 (0)