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)); + QualType sr = SR->getSymbol()->getType(); + if (!hasSameUnqualifiedPointeeType(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,16 @@ strcpy(x, y); // no-warning } +// PR37503 +void *func_strcpy_no_assertion(); +char ***ptr_strcpy_no_assertion; +void strcpy_no_assertion() { + *(unsigned char **)ptr_strcpy_no_assertion = (unsigned char *)(func_strcpy_no_assertion()); + char c; + strcpy(**ptr_strcpy_no_assertion, &c); // no-assertion +} + + //===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------=== Index: clang/test/Analysis/svalbuilder-float-cast.c =================================================================== --- clang/test/Analysis/svalbuilder-float-cast.c +++ clang/test/Analysis/svalbuilder-float-cast.c @@ -4,13 +4,9 @@ void SymbolCast_of_float_type_aux(int *p) { *p += 0; - // FIXME: Ideally, all unknown values should be symbolicated. - clang_analyzer_denote(*p, "$x"); // expected-warning{{Not a symbol}} - + clang_analyzer_denote(*p, "$x"); *p += 1; - // This should NOT be (float)$x + 1. Symbol $x was never casted to float. - // FIXME: Ideally, this should be $x + 1. - clang_analyzer_express(*p); // expected-warning{{Not a symbol}} + clang_analyzer_express(*p); // expected-warning{{$x + 1}} } void SymbolCast_of_float_type() {