Index: clang/lib/StaticAnalyzer/Core/Store.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/Store.cpp +++ clang/lib/StaticAnalyzer/Core/Store.cpp @@ -426,12 +426,17 @@ // We might need to do that for non-void pointers as well. // FIXME: We really need a single good function to perform casts for us // correctly every time we need it. - if (castTy->isPointerType() && !castTy->isVoidPointerType()) + if (castTy->isPointerType() && !castTy->isVoidPointerType()) { if (const auto *SR = dyn_cast_or_null(V.getAsRegion())) { QualType sr = SR->getSymbol()->getType(); if (!hasSameUnqualifiedPointeeType(sr, castTy)) - return loc::MemRegionVal(castRegion(SR, castTy)); + return loc::MemRegionVal(castRegion(SR, castTy)); } + // Next fixes pointer dereference using type different from its initial one + // See PR37503 for details + if (const auto *SR = dyn_cast_or_null(V.getAsRegion())) + return loc::MemRegionVal(castRegion(SR, castTy)); + } return svalBuilder.dispatchCast(V, castTy); } Index: clang/test/Analysis/nonloc-as-loc-crash.c =================================================================== --- /dev/null +++ clang/test/Analysis/nonloc-as-loc-crash.c @@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s +// expected-no-diagnostics + +void test(int *a, char ***b, float *c) { + *(unsigned char **)b = (unsigned char *)a; + if (**b == 0) // no-crash + ; + + *(unsigned char **)b = (unsigned char *)c; + if (**b == 0) // no-crash + ; +} Index: clang/test/Analysis/string.c =================================================================== --- clang/test/Analysis/string.c +++ clang/test/Analysis/string.c @@ -363,6 +363,14 @@ strcpy(x, y); // no-warning } +// PR37503 +void *get_void_ptr(); +char ***type_punned_ptr; +void strcpy_no_assertion(char c) { + *(unsigned char **)type_punned_ptr = (unsigned char *)(get_void_ptr()); + strcpy(**type_punned_ptr, &c); // no-crash +} + //===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------===