diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -10316,11 +10316,18 @@ const CastExpr *Cast) { SmallString<128> SizeString; llvm::raw_svector_ostream OS(SizeString); + + const clang::CastKind Kind = Cast->getCastKind(); + if (Kind == clang::CK_BitCast && + !Cast->getSubExpr()->getType()->isFunctionPointerType()) + return; + if (Kind == clang::CK_IntegralToPointer && + !isa( + Cast->getSubExpr()->IgnoreImplicitAsWritten()->IgnoreParens())) + return; + switch (Cast->getCastKind()) { case clang::CK_BitCast: - if (!Cast->getSubExpr()->getType()->isFunctionPointerType()) - return; - [[clang::fallthrough]]; case clang::CK_IntegralToPointer: case clang::CK_FunctionToPointerDecay: OS << '\''; diff --git a/clang/test/Analysis/free.c b/clang/test/Analysis/free.c --- a/clang/test/Analysis/free.c +++ b/clang/test/Analysis/free.c @@ -108,3 +108,11 @@ // expected-warning@-1{{Argument to free() is the address of the function 'iptr', which is not memory allocated by malloc()}} // expected-warning@-2{{attempt to call free on non-heap object 'iptr'}} } + +struct S { + const char* p; +}; + +void t18 (struct S s) { + free((void*)(unsigned long long)s.p); // no warning +} diff --git a/clang/test/Analysis/free.cpp b/clang/test/Analysis/free.cpp --- a/clang/test/Analysis/free.cpp +++ b/clang/test/Analysis/free.cpp @@ -208,3 +208,15 @@ // Unknown value std::free(x[offset]); // no-warning } + +struct S { + const char* p; +}; + +void t18a (S s) { + free((void*)(unsigned long long)s.p); // no warning +} + +void t18b (S s) { + std::free((void*)(unsigned long long)s.p); // no warning +}