ASDenysPetrov updated this revision to Diff 398986.
ASDenysPetrov added a comment.

Improved the checker. Reworked tests.


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

https://reviews.llvm.org/D114718

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
  clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp
  clang/test/Analysis/Checkers/StrictAliasingChecker/cv.cpp
  clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-ptr-to-scalar.cpp
  clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-var-to-scalar.cpp
  clang/test/Analysis/Checkers/StrictAliasingChecker/typedef.cpp

Index: clang/test/Analysis/Checkers/StrictAliasingChecker/typedef.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/Checkers/StrictAliasingChecker/typedef.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s
+// NOTE: -relaxed-aliasing flag disables StrictAliasing checker.
+
+typedef int MyInt;
+typedef MyInt MyAnotherInt;
+typedef char MyChar;
+typedef short MyShort;
+typedef MyChar *MyCharPtr;
+typedef MyShort *MyShortPtr;
+typedef MyInt *MyIntPtr;
+
+MyAnotherInt x = 42;
+
+void typedef_test() {
+  MyChar y1 = *(MyCharPtr)&x;   // no-warning
+  MyShort y2 = *(MyShortPtr)&x; // expected-warning{{Undefined behavior}}
+  MyInt y3 = *(MyIntPtr)&x;     // no-warning
+}
Index: clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-var-to-scalar.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-var-to-scalar.cpp
@@ -0,0 +1,650 @@
+// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s
+// NOTE: -relaxed-aliasing flag disables StrictAliasing checker.
+
+#define CHECK(var, type) \
+  { auto y = *(type *)&var; }
+
+void bool_test() {
+  bool x = true;
+  CHECK(x, bool) // no-warning
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void char_test() {
+  char x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void short_test() {
+  short x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void int_test() {
+  int x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_test() {
+  long x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_long_test() {
+  long long x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void schar_test() {
+  signed char x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uchar_test() {
+  unsigned char x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ushort_test() {
+  unsigned short x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uint_test() {
+  unsigned int x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_test() {
+  unsigned long x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_long_test() {
+  unsigned long long x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void float_test() {
+  float x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // no-warning
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void double_test() {
+  double x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // no-warning
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_double_test() {
+  long double x = 42;
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // no-warning
+}
+
+void bool_test(bool x) {
+  CHECK(x, bool) // no-warning
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void char_test(char x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void short_test(short x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void int_test(int x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_test(long x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_long_test(long long x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void schar_test(signed char x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uchar_test(unsigned char x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ushort_test(unsigned short x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uint_test(unsigned int x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_test(unsigned long x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_long_test(unsigned long long x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void float_test(float x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // no-warning
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void double_test(double x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // no-warning
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_double_test(long double x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // no-warning
+}
Index: clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-ptr-to-scalar.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-ptr-to-scalar.cpp
@@ -0,0 +1,561 @@
+// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s
+// NOTE: -relaxed-aliasing flag disables StrictAliasing checker.
+
+template <typename T>
+T *create();
+
+#define CHECK(var, type) \
+  { auto y = *(type *)var; }
+
+void bool_test() {
+  auto *x = create<bool>();
+  CHECK(x, bool) // no-warning
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void char_test() {
+  auto *x = create<char>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void short_test() {
+  auto *x = create<short>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void int_test() {
+  auto *x = create<int>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_test() {
+  auto *x = create<long>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_long_test() {
+  auto *x = create<long long>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void schar_test() {
+  auto *x = create<signed char>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uchar_test() {
+  auto *x = create<unsigned char>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ushort_test() {
+  auto *x = create<unsigned short>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uint_test() {
+  auto *x = create<unsigned int>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_test() {
+  auto *x = create<unsigned long>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_long_test() {
+  auto *x = create<unsigned long long>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void char_test(char *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void short_test(short *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+}
+
+void int_test(int *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_test(long *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_long_test(long long *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void schar_test(signed char *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uchar_test(unsigned char *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // no-warning
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+}
+
+void ushort_test(unsigned short *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // no-warning
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // no-warning
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void uint_test(unsigned int *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // no-warning
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // no-warning
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_test(unsigned long *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // no-warning
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // no-warning
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void ulong_long_test(unsigned long long *x) {
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // no-warning
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // no-warning
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void float_test() {
+  auto *x = create<float>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // no-warning
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void double_test() {
+  auto *x = create<double>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // no-warning
+  CHECK(x, long double) // expected-warning {{Undefined behavior}}
+}
+
+void long_double_test() {
+  auto *x = create<long double>();
+  CHECK(x, bool) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, char)      // no-warning
+  CHECK(x, short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, signed char)        // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned char)      // no-warning
+  CHECK(x, unsigned short)     // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned int)       // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long)      // expected-warning {{Undefined behavior}}
+  CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}}
+
+  CHECK(x, float)       // expected-warning {{Undefined behavior}}
+  CHECK(x, double)      // expected-warning {{Undefined behavior}}
+  CHECK(x, long double) // no-warning
+}
Index: clang/test/Analysis/Checkers/StrictAliasingChecker/cv.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/Checkers/StrictAliasingChecker/cv.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s
+// NOTE: -relaxed-aliasing flag disables StrictAliasing checker.
+
+#define CHECK_CV(var, type)         \
+  { auto y = *(type *)&var; }       \
+  { auto y = *(const type *)&var; } \
+  { auto y = *(const volatile type *)&var; }
+
+void cv_test() {
+  int x = 42;
+  CHECK_CV(x, char)  // no-warning
+  CHECK_CV(x, short) // expected-warning 3{{Undefined behavior}}
+
+  const int cx = 42;
+  CHECK_CV(cx, char)  // no-warning
+  CHECK_CV(cx, short) // expected-warning 3{{Undefined behavior}}
+
+  const volatile int cvx = 42;
+  CHECK_CV(cvx, char)  // no-warning
+  CHECK_CV(cvx, short) // expected-warning 3{{Undefined behavior}}
+}
Index: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp
===================================================================
--- /dev/null
+++ clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp
@@ -0,0 +1,207 @@
+//===- StrictAliasingChecker - ... ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// StrictAliasingChecker implements checks on violation of the next paragraph of
+// the Standard which is known as `Strict Aliasing Rule`.
+// C++20 7.2.1 p11 [basic.lval]:
+//  If a program attempts to access the stored value of an object through a
+//  glvalue whose type is not similar to one of the following types the behavior
+//  is undefined:
+//  - the dynamic type of the object,
+//  - a type that is the signed or unsigned type corresponding to the dynamic
+//    type of the object, or
+//  - a char, unsigned char, or std::byte type.
+//
+// NOTE: The checker operates only when strict-aliasing is enabled with
+// corresponding compiler flag.
+//
+// NOTE: There are differences in strict aliasing rules between C, C++
+// Standards. Now we only impelement checks since C++20 Standard (there were
+// changes applied in C++20 http://wg21.link/cwg2051).
+//
+// TODO: Support C++98/11/14/17. Shall we?
+// TODO: Support C.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+class AccessInferrer {
+  QualType From;
+  QualType To;
+  ASTContext &Ctx;
+
+public:
+  // Check whether the given types submit to the Strict Aliasing Rule.
+  //
+  // NOTE: User must provide canonical and unqualified QualType's for the
+  // correct result.
+  static bool canAccess(QualType From, QualType To, ASTContext &Ctx) {
+    // NOTE: Despite the function name `isCanonical()`, it also check whether
+    // the type is unqualified. (See implementation)
+    assert(From.isCanonical() && "The type shall be an unqualified canonical.");
+    assert(To.isCanonical() && "The type shall be an unqualified canonical.");
+    AccessInferrer AI(From, To, Ctx);
+    return AI.canAccessImpl();
+  }
+
+private:
+  AccessInferrer(QualType From, QualType To, ASTContext &Ctx)
+      : From(From), To(To), Ctx(Ctx) {}
+  bool canAccessImpl() {
+    return isSameDynamic() || isCharOrByte() || isOppositeSign();
+  }
+  // - the dynamic type of the object
+  bool isSameDynamic() { return From == To; }
+  // - a char, unsigned char, or std::byte type.
+  bool isCharOrByte() {
+    return To == Ctx.CharTy || To == Ctx.UnsignedCharTy || To->isStdByteType();
+  }
+  // - a type that is the signed or unsigned type corresponding to the dynamic
+  //   type of the object
+  bool isOppositeSign() {
+    // `char` type is a distinct type which has `signed char` or `unsigned char`
+    // as its underlying type. But there is nowhere in the Standard mentioned
+    // that `char` has corresponding signed/unsigned types and not mentioned
+    // that the stored value of an object can be accessed through a type which
+    // is similar to underlying type of the object.
+    // The same is true for other fundamental types (`bool`, `char8_t`,
+    // 'wchar_t', etc.) specified to have a signed or unsigned integer types as
+    // theirs underlying types.
+
+    if (const auto *BT = dyn_cast<BuiltinType>(To)) {
+      BuiltinType::Kind Kind = BT->getKind();
+      // `To` is unsigned.
+      if (((Kind >= BuiltinType::UShort) && (Kind <= BuiltinType::UInt128)) ||
+          (Kind == BuiltinType::UChar))
+        return From == Ctx.getCorrespondingSignedType(To);
+      // `To` is signed.
+      if (((Kind >= BuiltinType::Short) && (Kind <= BuiltinType::Int128)) ||
+          (Kind == BuiltinType::SChar))
+        return From == Ctx.getCorrespondingUnsignedType(To);
+    }
+
+    return false;
+  }
+};
+
+class StrictAliasingChecker : public Checker<check::PreStmt<UnaryOperator>,
+                                             check::PreStmt<ArraySubscriptExpr>,
+                                             check::PreStmt<MemberExpr>> {
+  BugType BT{this, "Strict Aliasing Rule",
+             "Access Violation through unallowed type."};
+
+public:
+  void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const {
+    // Handle indirection operator '*' only.
+    if (UO->getOpcode() == UO_Deref)
+      checkAccess(UO->getSubExpr(), UO->getType(), C);
+  }
+  void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const {
+    checkAccess(ASE->getBase(), ASE->getType(), C);
+  }
+  void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const {
+    const Expr *B = ME->getBase()->IgnoreParenBaseCasts();
+    checkAccess(B, B->getType()->getPointeeType(), C);
+  }
+
+private:
+  void checkAccess(const Expr *OrigEx, QualType AliasedTy,
+                   CheckerContext &C) const {
+    AliasedTy = getCanonicalUnqualifiedType(AliasedTy);
+    // TODO: Handle this case in a proper way, if any.
+    if (AliasedTy.isNull())
+      return;
+
+    const QualType OrigTy = getOriginalType(OrigEx, C);
+    // TODO: Handle this case in a proper way, if any.
+    if (OrigTy.isNull())
+      return;
+
+    if (!AccessInferrer::canAccess(OrigTy, AliasedTy, C.getASTContext()))
+      reportBug(C, OrigTy, AliasedTy);
+  }
+
+  // FIXME: Probably, we should have such function in QualType class.
+  // Existing `T->getCanonicalTypeUnqualified()` does not return unqualified
+  // type which, apparently, is expected.
+  QualType getCanonicalUnqualifiedType(QualType T) const {
+    if (!T.isNull()) {
+      T = T->getCanonicalTypeUnqualified();
+      T.removeLocalFastQualifiers();
+    }
+    return T;
+  }
+
+  QualType getOriginalType(const Expr *OrigEx, CheckerContext &C) const {
+    QualType T;
+
+    SVal V = C.getSVal(OrigEx->IgnoreParens());
+    if (V.isUnknownOrUndef())
+      return T;
+
+    if (auto MRV = V.getAs<loc::MemRegionVal>()) {
+      // Unwrap ElementRegion and CXXBaseObjectRegion nesting to get the base
+      // region.
+      const MemRegion *Base = MRV->getRegion()->StripCasts(true);
+      // Get type of the original declaration.
+      if (const auto *VR = dyn_cast<VarRegion>(Base))
+        T = VR->getValueType();
+      else if (const auto *SR = dyn_cast<SymbolicRegion>(Base))
+        T = SR->getSymbol()->getType()->getPointeeType();
+      // TODO: Support other regions in a proper way if would need.
+    }
+
+    // Get type from other types.
+    // NOTE: This is very inaccurate but it's better than NULL though.
+    if (T.isNull())
+      T = V.getType(C.getASTContext());
+
+    return getCanonicalUnqualifiedType(T);
+  }
+
+  void reportBug(CheckerContext &C, QualType From, QualType To) const {
+    SmallString<256> Buf;
+    llvm::raw_svector_ostream OS(Buf);
+    OS << "Undefined behavior. Attempting to access the stored value of type ";
+    OS << "'" << From.getAsString() << "'";
+    OS << " through unallowed type ";
+    OS << "'" << To.getAsString() << "'.";
+
+    ExplodedNode *Node = C.generateNonFatalErrorNode();
+    auto Report = std::make_unique<PathSensitiveBugReport>(BT, OS.str(), Node);
+    C.emitReport(std::move(Report));
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Registration.
+//===----------------------------------------------------------------------===//
+
+void ento::registerStrictAliasingChecker(CheckerManager &CM) {
+  CM.registerChecker<StrictAliasingChecker>();
+}
+
+bool ento::shouldRegisterStrictAliasingChecker(const CheckerManager &CM) {
+  const LangOptions &LO = CM.getLangOpts();
+  const bool IsStrictAliasing = !CM.getCodeGenOpts().RelaxedAliasing;
+  // Support from C++20 for now.
+  // TODO: Support C++98/11/14/17. Shall we?
+  // TODO: Support C.
+  return IsStrictAliasing && (LO.CPlusPlus20 || LO.CPlusPlus2b);
+}
Index: clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -105,6 +105,7 @@
   StdLibraryFunctionsChecker.cpp
   STLAlgorithmModeling.cpp
   StreamChecker.cpp
+  StrictAliasingChecker.cpp
   StringChecker.cpp
   Taint.cpp
   TaintTesterChecker.cpp
Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
===================================================================
--- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -298,6 +298,12 @@
   Dependencies<[PthreadLockBase]>,
   Documentation<HasAlphaDocumentation>;
 
+def StrictAliasingChecker : Checker<"StrictAliasing">,
+  HelpText<"Check conformity with Strict Alising Rule. Check an access to the "
+           "stored value through a glvalue whose type is not allowed by "
+           "the Standard. ([basic.lval])">,
+  Documentation<HasAlphaDocumentation>;
+
 } // end "alpha.core"
 
 //===----------------------------------------------------------------------===//
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to