Skip to content

Commit ec01a3e

Browse files
authored
Merge branch 'main' into dynamic-capabilities
2 parents 82ace5b + 34c011d commit ec01a3e

File tree

42 files changed

+614
-492
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+614
-492
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,8 @@ Bug Fixes in This Version
685685
- Fixed an assertion failure in serialization of constexpr structs containing unions. (#GH140130)
686686
- Fixed duplicate entries in TableGen that caused the wrong attribute to be selected. (GH#140701)
687687
- Fixed type mismatch error when 'builtin-elementwise-math' arguments have different qualifiers, this should be well-formed. (#GH141397)
688+
- Constant evaluation now correctly runs the destructor of a variable declared in
689+
the second clause of a C-style ``for`` loop. (#GH139818)
688690

689691
Bug Fixes to Compiler Builtins
690692
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5761,8 +5761,12 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
57615761
if (FS->getCond() && !EvaluateCond(Info, FS->getConditionVariable(),
57625762
FS->getCond(), Continue))
57635763
return ESR_Failed;
5764-
if (!Continue)
5764+
5765+
if (!Continue) {
5766+
if (!IterScope.destroy())
5767+
return ESR_Failed;
57655768
break;
5769+
}
57665770

57675771
EvalStmtResult ESR = EvaluateLoopBody(Result, Info, FS->getBody());
57685772
if (ESR != ESR_Continue) {

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
11351135
emitGlobalOpenACCDecl(cast<OpenACCDeclareDecl>(decl));
11361136
break;
11371137
case Decl::Enum:
1138+
case Decl::Using: // using X; [C++]
11381139
case Decl::UsingDirective: // using namespace X; [C++]
11391140
case Decl::Typedef:
11401141
case Decl::TypeAlias: // using foo = bar; [C++11]
@@ -1143,6 +1144,10 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
11431144
assert(!cir::MissingFeatures::generateDebugInfo());
11441145
break;
11451146

1147+
// No code generation needed.
1148+
case Decl::UsingShadow:
1149+
break;
1150+
11461151
// C++ Decls
11471152
case Decl::LinkageSpec:
11481153
case Decl::Namespace:

clang/test/CIR/CodeGen/namespace.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,46 @@ int f4(void) {
5050
// CHECK: %[[G3_ADDR:.*]] = cir.get_global @_ZN4test5test22g3E : !cir.ptr<!s32i>
5151
// CHECK: %[[G3_VAL:.*]] = cir.load{{.*}} %[[G3_ADDR]] : !cir.ptr<!s32i>, !s32i
5252
// CHECK: %[[SUM2:.*]] = cir.binop(add, %[[SUM]], %[[G3_VAL]]) nsw : !s32i
53+
54+
using test2::f3;
55+
using test2::g3;
56+
57+
int f5() {
58+
f3();
59+
return g3;
60+
}
61+
62+
// CHECK: cir.func @_Z2f5v()
63+
// CHECK: cir.call @_ZN4test5test22f3Ev()
64+
// CHECK: %[[G3_ADDR:.*]] = cir.get_global @_ZN4test5test22g3E : !cir.ptr<!s32i>
65+
// CHECK: %[[G3_VAL:.*]] = cir.load{{.*}} %[[G3_ADDR]] : !cir.ptr<!s32i>, !s32i
66+
67+
namespace test3 {
68+
struct S {
69+
int a;
70+
} s;
71+
}
72+
73+
using test3::s;
74+
75+
int f6() {
76+
return s.a;
77+
}
78+
79+
// CHECK: cir.func @_Z2f6v()
80+
// CHECK: cir.get_global @_ZN5test31sE : !cir.ptr<!rec_test33A3AS>
81+
// CHECK: cir.get_member %{{.*}}[0] {name = "a"}
82+
83+
int shadowedFunc() {
84+
return 3;
85+
}
86+
87+
namespace shadow {
88+
using ::shadowedFunc;
89+
}
90+
91+
void f7() {
92+
shadow::shadowedFunc();
93+
}
94+
95+
// CHECK: cir.func @_Z2f7v()

clang/test/SemaCXX/gh139818.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify -fcxx-exceptions
2+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify -fexperimental-new-constant-interpreter -fcxx-exceptions
3+
4+
namespace GH139818{
5+
struct A {
6+
constexpr ~A() { ref = false; }
7+
constexpr operator bool() {
8+
return b;
9+
}
10+
bool b;
11+
bool& ref;
12+
};
13+
14+
constexpr bool f1() {
15+
bool ret = true;
16+
for (bool b = false; A x{b, ret}; b = true) {}
17+
return ret;
18+
}
19+
20+
static_assert(!f1());
21+
22+
struct Y {
23+
constexpr ~Y() noexcept(false) { throw "oops"; } // expected-note {{subexpression not valid in a constant expression}}
24+
25+
constexpr operator bool() {
26+
return b;
27+
}
28+
bool b;
29+
};
30+
constexpr bool f2() {
31+
for (bool b = false; Y x = {b}; b = true) {} // expected-note {{in call to 'x.~Y()'}}
32+
return true;
33+
}
34+
static_assert(f2()); // expected-error {{static assertion expression is not an integral constant expression}}
35+
// expected-note@-1 {{in call to 'f2()'}}
36+
};

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool:
315315
return keepGoing
316316

317317
def _process_continued(self, all_threads_continued: bool):
318-
self.threads = None
319318
self.frame_scopes = {}
320319
if all_threads_continued:
321320
self.thread_stop_reasons = {}
@@ -1191,6 +1190,9 @@ def request_threads(self):
11911190
with information about all threads"""
11921191
command_dict = {"command": "threads", "type": "request", "arguments": {}}
11931192
response = self.send_recv(command_dict)
1193+
if not response["success"]:
1194+
self.threads = None
1195+
return response
11941196
body = response["body"]
11951197
# Fill in "self.threads" correctly so that clients that call
11961198
# self.get_threads() or self.get_thread_id(...) can get information

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,10 @@ void DAP::EventThread() {
12401240
// automatically restarted.
12411241
if (!lldb::SBProcess::GetRestartedFromEvent(event)) {
12421242
SendStdOutStdErr(*this, process);
1243-
SendThreadStoppedEvent(*this);
1243+
if (llvm::Error err = SendThreadStoppedEvent(*this))
1244+
DAP_LOG_ERROR(log, std::move(err),
1245+
"({1}) reporting thread stopped: {0}",
1246+
transport.GetClientName());
12441247
}
12451248
break;
12461249
case lldb::eStateRunning:

lldb/tools/lldb-dap/DAP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ struct DAP {
152152
llvm::DenseSet<ClientFeature> clientFeatures;
153153

154154
/// The initial thread list upon attaching.
155-
std::optional<llvm::json::Array> initial_thread_list;
155+
std::vector<protocol::Thread> initial_thread_list;
156156

157157
/// Keep track of all the modules our client knows about: either through the
158158
/// modules request or the module events.

lldb/tools/lldb-dap/EventHelper.cpp

Lines changed: 67 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
#include "EventHelper.h"
1010
#include "DAP.h"
11-
#include "DAPLog.h"
11+
#include "DAPError.h"
1212
#include "JSONUtils.h"
1313
#include "LLDBUtils.h"
1414
#include "Protocol/ProtocolEvents.h"
1515
#include "Protocol/ProtocolTypes.h"
1616
#include "lldb/API/SBFileSpec.h"
17+
#include "llvm/Support/Error.h"
1718

1819
#if defined(_WIN32)
1920
#define NOMINMAX
@@ -24,6 +25,8 @@
2425
#endif
2526
#endif
2627

28+
using namespace llvm;
29+
2730
namespace lldb_dap {
2831

2932
static void SendThreadExitedEvent(DAP &dap, lldb::tid_t tid) {
@@ -134,78 +137,78 @@ void SendProcessEvent(DAP &dap, LaunchMethod launch_method) {
134137

135138
// Send a thread stopped event for all threads as long as the process
136139
// is stopped.
137-
void SendThreadStoppedEvent(DAP &dap) {
140+
llvm::Error SendThreadStoppedEvent(DAP &dap, bool on_entry) {
141+
lldb::SBMutex lock = dap.GetAPIMutex();
142+
std::lock_guard<lldb::SBMutex> guard(lock);
143+
138144
lldb::SBProcess process = dap.target.GetProcess();
139-
if (process.IsValid()) {
140-
auto state = process.GetState();
141-
if (state == lldb::eStateStopped) {
142-
llvm::DenseSet<lldb::tid_t> old_thread_ids;
143-
old_thread_ids.swap(dap.thread_ids);
144-
uint32_t stop_id = process.GetStopID();
145-
const uint32_t num_threads = process.GetNumThreads();
145+
if (!process.IsValid())
146+
return make_error<DAPError>("invalid process");
146147

147-
// First make a pass through the threads to see if the focused thread
148-
// has a stop reason. In case the focus thread doesn't have a stop
149-
// reason, remember the first thread that has a stop reason so we can
150-
// set it as the focus thread if below if needed.
151-
lldb::tid_t first_tid_with_reason = LLDB_INVALID_THREAD_ID;
152-
uint32_t num_threads_with_reason = 0;
153-
bool focus_thread_exists = false;
154-
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
155-
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
156-
const lldb::tid_t tid = thread.GetThreadID();
157-
const bool has_reason = ThreadHasStopReason(thread);
158-
// If the focus thread doesn't have a stop reason, clear the thread ID
159-
if (tid == dap.focus_tid) {
160-
focus_thread_exists = true;
161-
if (!has_reason)
162-
dap.focus_tid = LLDB_INVALID_THREAD_ID;
163-
}
164-
if (has_reason) {
165-
++num_threads_with_reason;
166-
if (first_tid_with_reason == LLDB_INVALID_THREAD_ID)
167-
first_tid_with_reason = tid;
168-
}
169-
}
148+
lldb::StateType state = process.GetState();
149+
if (!lldb::SBDebugger::StateIsStoppedState(state))
150+
return make_error<NotStoppedError>();
170151

171-
// We will have cleared dap.focus_tid if the focus thread doesn't have
172-
// a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
173-
// then set the focus thread to the first thread with a stop reason.
174-
if (!focus_thread_exists || dap.focus_tid == LLDB_INVALID_THREAD_ID)
175-
dap.focus_tid = first_tid_with_reason;
152+
llvm::DenseSet<lldb::tid_t> old_thread_ids;
153+
old_thread_ids.swap(dap.thread_ids);
154+
uint32_t stop_id = process.GetStopID();
155+
const uint32_t num_threads = process.GetNumThreads();
176156

177-
// If no threads stopped with a reason, then report the first one so
178-
// we at least let the UI know we stopped.
179-
if (num_threads_with_reason == 0) {
180-
lldb::SBThread thread = process.GetThreadAtIndex(0);
181-
dap.focus_tid = thread.GetThreadID();
182-
dap.SendJSON(CreateThreadStopped(dap, thread, stop_id));
183-
} else {
184-
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
185-
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
186-
dap.thread_ids.insert(thread.GetThreadID());
187-
if (ThreadHasStopReason(thread)) {
188-
dap.SendJSON(CreateThreadStopped(dap, thread, stop_id));
189-
}
190-
}
191-
}
157+
// First make a pass through the threads to see if the focused thread
158+
// has a stop reason. In case the focus thread doesn't have a stop
159+
// reason, remember the first thread that has a stop reason so we can
160+
// set it as the focus thread if below if needed.
161+
lldb::tid_t first_tid_with_reason = LLDB_INVALID_THREAD_ID;
162+
uint32_t num_threads_with_reason = 0;
163+
bool focus_thread_exists = false;
164+
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
165+
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
166+
const lldb::tid_t tid = thread.GetThreadID();
167+
const bool has_reason = ThreadHasStopReason(thread);
168+
// If the focus thread doesn't have a stop reason, clear the thread ID
169+
if (tid == dap.focus_tid) {
170+
focus_thread_exists = true;
171+
if (!has_reason)
172+
dap.focus_tid = LLDB_INVALID_THREAD_ID;
173+
}
174+
if (has_reason) {
175+
++num_threads_with_reason;
176+
if (first_tid_with_reason == LLDB_INVALID_THREAD_ID)
177+
first_tid_with_reason = tid;
178+
}
179+
}
192180

193-
for (auto tid : old_thread_ids) {
194-
auto end = dap.thread_ids.end();
195-
auto pos = dap.thread_ids.find(tid);
196-
if (pos == end)
197-
SendThreadExitedEvent(dap, tid);
181+
// We will have cleared dap.focus_tid if the focus thread doesn't have
182+
// a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
183+
// then set the focus thread to the first thread with a stop reason.
184+
if (!focus_thread_exists || dap.focus_tid == LLDB_INVALID_THREAD_ID)
185+
dap.focus_tid = first_tid_with_reason;
186+
187+
// If no threads stopped with a reason, then report the first one so
188+
// we at least let the UI know we stopped.
189+
if (num_threads_with_reason == 0) {
190+
lldb::SBThread thread = process.GetThreadAtIndex(0);
191+
dap.focus_tid = thread.GetThreadID();
192+
dap.SendJSON(CreateThreadStopped(dap, thread, stop_id));
193+
} else {
194+
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
195+
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
196+
dap.thread_ids.insert(thread.GetThreadID());
197+
if (ThreadHasStopReason(thread)) {
198+
dap.SendJSON(CreateThreadStopped(dap, thread, stop_id));
198199
}
199-
} else {
200-
DAP_LOG(
201-
dap.log,
202-
"error: SendThreadStoppedEvent() when process isn't stopped ({0})",
203-
lldb::SBDebugger::StateAsCString(state));
204200
}
205-
} else {
206-
DAP_LOG(dap.log, "error: SendThreadStoppedEvent() invalid process");
207201
}
202+
203+
for (const auto &tid : old_thread_ids) {
204+
auto end = dap.thread_ids.end();
205+
auto pos = dap.thread_ids.find(tid);
206+
if (pos == end)
207+
SendThreadExitedEvent(dap, tid);
208+
}
209+
208210
dap.RunStopCommands();
211+
return Error::success();
209212
}
210213

211214
// Send a "terminated" event to indicate the process is done being

lldb/tools/lldb-dap/EventHelper.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLDB_TOOLS_LLDB_DAP_EVENTHELPER_H
1111

1212
#include "DAPForward.h"
13+
#include "llvm/Support/Error.h"
1314

1415
namespace lldb_dap {
1516
struct DAP;
@@ -21,7 +22,7 @@ void SendTargetBasedCapabilities(DAP &dap);
2122

2223
void SendProcessEvent(DAP &dap, LaunchMethod launch_method);
2324

24-
void SendThreadStoppedEvent(DAP &dap);
25+
llvm::Error SendThreadStoppedEvent(DAP &dap, bool on_entry = false);
2526

2627
void SendTerminatedEvent(DAP &dap);
2728

0 commit comments

Comments
 (0)