[clang] [analyzer] Treat break, continue, goto, and label statements as trivial in WebKit checkers. (PR #91873)

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Mon May 13 20:46:14 PDT 2024


================
@@ -445,6 +456,10 @@ class TrivialFunctionAnalysisVisitor
     return Visit(VMT->getSubExpr());
   }
 
+  bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr* BTE) {
+    return Visit(BTE->getSubExpr());
----------------
haoNoQ wrote:

At this point you probably want to double-check that the destructor itself is trivial (in the sense of your analysis, not in the general C++ sense). Destructor calls are generally not represented in the AST at all (unless they're explicit), CodeGen just figures them out from the rest of the syntax.

`CXXBindTemporaryExpr` is probably the right place to look for destructors, at least according to me after reading a lot of ASTs. But at the same time nobody really understands what `CXXBindTemporaryExpr` stands for anymore and a few famous people have argued for removing it.

Note that `CXXBindTemporaryExpr` doesn't guarantee that there will be a destructor call at the end of the full-expression (lifetime extension is a thing - need to consult `MaterializeTemporaryExpr` to see where this is going), or even at the end of function (RVO is a thing), even when the constructor is targeting a local variable (NRVO is a thing). In case of RVO/NRVO the caller doesn't necessarily call the destructor either; it could also be RVOing/NRVOing it further up the call stack up to arbitrarily large depth.

In pre-C++17 AST, and even in C++17 and later if NRVO is involved, the AST would look as if a copy/move is being made even if it's elided in practice.

So when checking the destructor, you need to think how far do you want to go when it comes to determining if the destructor actually happens by the time the function returns. Because in order to implement this accurately you'll need to re-implement a big chunk of CodeGen.

You can also try to check the destructor inside `VisitCXXConstructExpr()`, as if assuming that every time an object is constructed, it'd be deleted "eventually". Except in this case you'll miss the part where you're receiving an object by value from a `CallExpr` (and such); then you'll also need to check the destructor for the received object even though you don't see the constructor. This isn't a problem when you're relying on `CXXBindTemporaryExpr` which will be present around the `CallExpr` normally when the object needs a destructor.

https://github.com/llvm/llvm-project/pull/91873


More information about the cfe-commits mailing list