This is an archive of the discontinued LLVM Phabricator instance.

[-Wunsafe-buffer-usage] Add AST info to the unclaimed DRE debug notes for analysis
ClosedPublic

Authored by ziqingluo-90 on Aug 22 2023, 3:55 PM.

Details

Summary

The debug note for an unclaimed DRE highlights a usage of an unsafe pointer that is not supported by our analysis.

For a better understand of what the unsupported cases are, we add more information to the debug note---a string of ancestor AST nodes of the unclaimed DRE. For example, an unclaimed DRE p in an expression *(p++) will result in a string starting with DRE, UnaryOperator(++), Paren, UnaryOperator(*).

To find out the most common patterns of those unsupported use cases, we add a simple script to build a prefix tree over those strings and count each prefix. The script reads input line by line, assumes a line is a list of words separated by ,s, and builds a prefix tree over those lists.

Diff Detail

Event Timeline

ziqingluo-90 created this revision.Aug 22 2023, 3:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 22 2023, 3:55 PM
ziqingluo-90 requested review of this revision.Aug 22 2023, 3:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 22 2023, 3:55 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
ziqingluo-90 edited the summary of this revision. (Show Details)Aug 22 2023, 3:55 PM
t-rasmud accepted this revision.Sep 18 2023, 2:33 PM
This revision is now accepted and ready to land.Sep 18 2023, 2:33 PM
NoQ added a comment.Sep 20 2023, 2:58 PM

I like where this is going, and I appreciate the test! Tests for tiny debug utilities aren't critical for the compiler, but they're a great way to demonstrate and document how to invoke the script and how it's supposed to work.

clang/lib/Analysis/UnsafeBufferUsage.cpp
38–39

Maybe just use something else as a separator, like ==> ? (Python .split() method will eat that happily.)

56

This looks like a manual reimplementation of a StmtVisitor. Maybe just use it directly?

class StmtDebugPrinter : public ConstStmtVisitor<StmtDebugPrinter, std::optional<std::string>> {
public:
  std::optional<std::string> VisitStmt(const Stmt *S) {
    return S->getStmtClassName();
  }
  std::optional<std::string> VisitBinaryOperator(const BinaryOperator *BO) {
    // Customize...
  }
};
clang/test/SemaCXX/warn-unsafe-buffer-usage-debug-unclaimed.cpp
10 ↗(On Diff #556070)

You probably need to do something similar to test/Analysis/exploded-graph-rewriter/lit.local.cfg, to properly discover the right python executable which may not be straightforward on some buildbots (imagine Windows!).

clang/utils/analyze_safe_buffer_debug_notes.py
30–34

A bit more idiomatic I think (might behave differently around linebreaks).

Address comments.

ziqingluo-90 marked 4 inline comments as done.Sep 25 2023, 2:18 PM
NoQ added inline comments.Oct 3 2023, 2:54 PM
clang/test/SemaCXX/warn-unsafe-buffer-usage-debug-unclaimed/lit.local.cfg
6

I might be overthinking/cargo-culting, but folks seem to never expose the python executable on its own, instead make a substitution for the entire tool. They also seem to use config.python_executable instead of sys.executable, though it's probably always the same no matter how they override it. Still, I might be missing some weird interactions. I think it's better to just do whatever everyone else does, something along the lines of

config.substitutions.append(
  (
    "%analyze_safe_buffer_debug_notes",
    "'%s' %s % (
      config.python_executable,
      os.path.join(config.clang_src_dir, "utils", "analyze_safe_buffer_debug_notes.py")
    )
  )
)

Also forward slashes will probably fail on Windows, so I can see how os.path.join is necessary. Though I suspect we will anyway end up with UNSUPPORTED: system-windows or REQUIRES: shell one way or another.

address comments

ziqingluo-90 marked an inline comment as done.Oct 3 2023, 4:48 PM
NoQ accepted this revision.Oct 19 2023, 1:00 PM

Thanks! Looks great now, let's try to land this!