================
@@ -3842,10 +3866,146 @@ bool Compiler<Emitter>::VisitPredefinedExpr(const
PredefinedExpr *E) {
template <class Emitter>
bool Compiler<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {
- if (E->getSubExpr() && !this->discard(E->getSubExpr()))
+ const Expr *SubExpr = E->getSubExpr();
+ if (!Ctx.ExceptionsEnabled) {
+ if (SubExpr && !this->discard(SubExpr))
+ return false;
+ return this->emitInvalid(E);
+ }
+
+ if (!SubExpr)
+ return this->emitReThrow(E);
+
+ QualType ExceptionType = SubExpr->getType();
+ OptPrimType ExceptionT = classify(SubExpr);
+
+ const Descriptor *Desc;
+ if (ExceptionT)
+ Desc = P.createDescriptor(SubExpr, *ExceptionT);
+ else
+ Desc = P.createDescriptor(SubExpr, ExceptionType.getTypePtr(),
+ /*IsConst=*/false);
+
+ if (!this->emitAllocException(Desc, E))
+ return false;
+
+ if (ExceptionT) {
+ if (!this->visit(SubExpr))
+ return false;
+ if (!this->emitInit(*ExceptionT, E))
+ return false;
+ } else {
+ if (!this->visitInitializer(SubExpr))
+ return false;
+ }
+
+ OptPrimType T = classify(E->getSubExpr()->getType());
+ if (!this->emitSaveException(ExceptionType.getTypePtr(), T, E))
return false;
- return this->emitInvalid(E);
+ this->VarScope->destroyLocals();
----------------
zwuis wrote:
Only variables in the innermost scope are destroyed.
<details>
<summary>Reproducer</summary>
```cpp
struct Inc {
int &m;
constexpr Inc(int &m) : m(m) {}
constexpr ~Inc() { ++m; }
};
constexpr int a() { throw 12; };
constexpr int f() {
int m = 10;
try {
Inc _(m);
a();
} catch (int) {
return m;
}
}
static_assert(f() == 11);
constexpr int g() {
int m = 10;
try {
Inc _(m);
{
Inc _(m);
throw 12;
}
} catch (int) {
return m;
}
}
static_assert(g() == 12);
```
</details>
https://github.com/llvm/llvm-project/pull/189410
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits