[PATCH] D114718: [analyzer] Implement a new checker for Strict Aliasing Rule.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 29 12:57:06 PST 2021


NoQ added a comment.

Awesome, I love it!

What would it take to enable this by default? Note that we can enable the checker without emitting any warnings; sinking exotic execution paths (on which strict aliasing is known to be violated) is valuable on its own.

Other than that, we'll probably need a bug visitor to add a note for where the original type comes from (it should probably be the place where the location becomes *live*), and then some real-world testing.



================
Comment at: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp:48-49
+  //
+  // NOTE: User must provide canonical and unqualified QualType's for the
+  // correct result.
+  static bool canAccess(QualType From, QualType To, ASTContext &Ctx) {
----------------
`assert()` it? Or maybe canonicalize defensively so that not to duplicate code in the caller, given that there's really only one correct way to do that?


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp:80
+class StrictAliasingChecker : public Checker<check::Location> {
+  mutable std::unique_ptr<BugType> BT;
+
----------------
The modern solution is
```lang=c++
BugType BT{this, "...", "..."};
```


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp:113
+  QualType getOriginalType(CheckerContext &C, SVal V, QualType T) const {
+    assert(V.getAs<Loc>() && "Location shall be a Loc.");
+    V = C.getState()->getSVal(V.castAs<Loc>(), T);
----------------
I suspect it might also be `UnknownVal` (?) It usually makes sense to protect against such scenarios with an early return.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp:141-145
+    auto ER = dyn_cast<ElementRegion>(R);
+    while (ER) {
+      R = ER->getSuperRegion();
+      ER = dyn_cast<ElementRegion>(R);
+    }
----------------
You're basically running into https://bugs.llvm.org/show_bug.cgi?id=43364 here. The element region is not necessarily a consequence of a pointer cast; it may also be a legitimate array element access, and there's no way to figure out what it really was. So I suspect that you may fail the following test case:
```lang=c++
void foo() {
  int x[10];
  int *p = &x[1];
  *p = 1; // int incompatible with int[10]
}
```

Separately from that, ultimatetly you'll most likely have to handle //regions with symbolic base// separately. These regions are special because they are built when the information about the original type is not really unavailable. For now you're dodging this problem by only supporting `VarRegion`s with element sub-regions. But in the general case you may encounter code like this
```lang=c++
void foo(void *p) {
  int *x = p;
  float *y = x;
  *y = 1.0;
}
```
which may be valid if the original pointer `p` points to a `float`. But this can be delayed until later.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp:157
+
+    ExplodedNode *Node = C.generateNonFatalErrorNode();
+    if (!BT)
----------------
I suggest a fatal error node. Undefined behavior already occured, there's nothing interesting in the follow-up.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp:178-179
+  const LangOptions &LO = CM.getLangOpts();
+  // Ideally, the condition should be `LO.CPlusPlus11 || LO.CPlusPlus2b` but
+  // implemented checks can be partially applied for C++17 and lower versions.
+  return LO.CPlusPlus;
----------------
We should probably keep the checker disabled in these language modes until we're sure it works correctly (in a conservative sense, i.e. doesn't emit false positives).

Can we check whether `-fstrict-aliasing` is enabled here? That's probably appropriate.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114718/new/

https://reviews.llvm.org/D114718



More information about the cfe-commits mailing list