diff options
author | Ziqing Luo <ziqing@udel.edu> | 2024-11-18 15:59:48 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-18 15:59:48 -0800 |
commit | 78606af606deca9dd4de2ac1aec17a966c114bc2 (patch) | |
tree | 777a6b189df209b64231c99fae4942c92ce98ecb /clang/lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 6e2b77d4696d4a672635c0ba1ead4824e2158a7d (diff) | |
download | llvm-78606af606deca9dd4de2ac1aec17a966c114bc2.zip llvm-78606af606deca9dd4de2ac1aec17a966c114bc2.tar.gz llvm-78606af606deca9dd4de2ac1aec17a966c114bc2.tar.bz2 |
[-Wunsafe-buffer-usage] Fix bug in unsafe casts to incomplete types (#116433)
Fixed the crash coming from attempting to get size of incomplete types.
Casting `span.data()` to a pointer-to-incomplete-type should be
immediately considered unsafe.
Solving issue #116286.
Co-authored-by: Ziqing Luo <ziqing_luo@apple.com>
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index f11fd3a..075c0df 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -2262,19 +2262,28 @@ public: MsgParam = 5; } else if (const auto *ECE = dyn_cast<ExplicitCastExpr>(Operation)) { QualType destType = ECE->getType(); + bool destTypeComplete = true; + if (!isa<PointerType>(destType)) return; + destType = destType.getTypePtr()->getPointeeType(); + if (const auto *D = destType->getAsTagDecl()) + destTypeComplete = D->isCompleteDefinition(); - const uint64_t dSize = - Ctx.getTypeSize(destType.getTypePtr()->getPointeeType()); + // If destination type is incomplete, it is unsafe to cast to anyway, no + // need to check its type: + if (destTypeComplete) { + const uint64_t dSize = Ctx.getTypeSize(destType); + QualType srcType = ECE->getSubExpr()->getType(); - QualType srcType = ECE->getSubExpr()->getType(); - const uint64_t sSize = - Ctx.getTypeSize(srcType.getTypePtr()->getPointeeType()); + assert(srcType->isPointerType()); - if (sSize >= dSize) - return; + const uint64_t sSize = + Ctx.getTypeSize(srcType.getTypePtr()->getPointeeType()); + if (sSize >= dSize) + return; + } if (const auto *CE = dyn_cast<CXXMemberCallExpr>( ECE->getSubExpr()->IgnoreParens())) { D = CE->getMethodDecl(); |