[llvm-branch-commits] [clang] [analyzer] Rename DanglingPtrDeref to StackUseAfterScope and move it to core (PR #233889)

Benedek Kaibas via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Oct 20 09:57:28 PDT 2026


================
@@ -159,12 +159,11 @@ void simpleMoveCtorTest() {
     clang_analyzer_printState();
 
 // CHECK:      "checker_messages": [
-// CHECK-NEXT:   { "checker": "cplusplus.Move", "messages": [
+// CHECK:        { "checker": "cplusplus.Move", "messages": [
----------------
benedekaibas wrote:

After making the changes and running the lit test this test file was failing with the following error:
```text
# | /Users/benedekaibas/Documents/llvm-project/clang/test/Analysis/use-after-move.cpp:167:16: error: CHECK-NEXT: is not on the line after the previous match
# | // CHECK-NEXT: ]
# |                ^
# | <stdin>:30:2: note: 'next' match was here
# |  ]}
# |  ^
# | <stdin>:24:4: note: previous match ended here
# |  ]},
# |    ^
# | <stdin>:25:1: note: non-matching line after previous match is here
# |  { "checker": "core.LifetimeModeling", "messages": [
# | ^
# |
# | Input file: <stdin>
# | Check file: /Users/benedekaibas/Documents/llvm-project/clang/test/Analysis/use-after-move.cpp
# |
# | -dump-input=help explains the following input dump.
# |
# | Input was:
# | <<<<<<
# |             .
# |             .
# |             .
# |            19:  { "checker": "cplusplus.Move", "messages": [
# |            20:  "Moved-from objects :",
# |            21:  "a.b: moved",
# |            22:  "a: moved",
# |            23:  ""
# |            24:  ]},
# | next:167'0       {    search range start (exclusive)
# |            25:  { "checker": "core.LifetimeModeling", "messages": [
# |            26:  "LifetimeBound bindings:",
# |            27:  " Origin &a.b contains Loan a.b",
# |            28:  " Origin &a contains Loan a",
# |            29:  ""
# |            30:  ]}
# | next:167'1      !    error: match on wrong line
# |            31:  ]
# |            32: }"program_state": {
# |            33:  "store": { "pointer": "0x972eb5620", "items": [
# |            34:  { "cluster": "a", "pointer": "0x972f6f3c0", "items": [
# |            35:  { "kind": "Direct", "offset": 0, "value": "42 S32b" },
# |             .
# |             .
# |             .                                                                                # |            58:  " Origin &a.b contains Loan a.b",
# |            59:  " Origin &a contains Loan a",
# |            60:  ""
# |            61:  ]}
# |            62:  ]
# |            63: }
# | next:167'2      } search range end (exclusive)
# | >>>>>>
```

The `LifetimeModeling` checker's message appears here because the `LifetimeModeling` checker prints its state when there are lifetime bindings. The `printState()` in lfietime modeling checks whether the state is non-empty, so when there are no lifetime bindings `printState` does not record anything. However, just updating the `CHECK` lines with the new message is non sufficient since the `runCheckersForPrintStateJson` function iterates the `llvm::DenseMap<CheckerTag, std::unique_ptr<CheckerBackend>> CheckerTags` by their hash number which is non-deterministic. It is non-deterministic because even when I include the `LifetimeModeling` messages the order of the hash number can vary between runs. For some runs the `LifetimeModeling` messages came first and for some it was the MoveChecker's messages. The `tag` is used as the map key:
```cpp
  CHECKER *getChecker(AT &&...Args) {
    CheckerTag Tag = getTag<CHECKER>();

    std::unique_ptr<CheckerBackend> &Ref = CheckerTags[Tag];
```

The hash can vary run to run because the keys are `tag` pointers and those addresses differ from one process to the next:
```cpp
  template <typename T>
  static void *getTag() { static int tag; return &tag; }
```

Current test files are not failing because each state dump contains only one checker's block. `CHECK` scans forward past `LifetimeModeling`'s block if it happens to come first which fixes the test file, but not the underlying problem.

I propose that I make the fix in another PR where instead of iterating over the `DenseMap` by the hash number I iterate based on the checkers' name (there might be other possible fix for this, but for the first glance this is what comes ot my mind).

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


More information about the llvm-branch-commits mailing list