-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[-Wunsafe-buffer-usage] Fix a bug and suppress libc warnings for C files #109496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[-Wunsafe-buffer-usage] Fix a bug and suppress libc warnings for C files #109496
Conversation
ziqingluo-90
commented
Sep 20, 2024
- Fix a bug in UnsafeBufferUsage.cpp related to casting to PointerType (report by @hnrklssn here)
- Suppress -Wunsafe-buffer-usage-in-libc-call for C files
@llvm/pr-subscribers-clang-analysis Author: Ziqing Luo (ziqingluo-90) Changes
Full diff: https://github.com/llvm/llvm-project/pull/109496.diff 3 Files Affected:
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index a16762244b1766..110a121e71a7d2 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -250,7 +250,9 @@ AST_MATCHER_P(Stmt, ignoreUnsafeBufferInContainer,
AST_MATCHER_P(Stmt, ignoreUnsafeLibcCall, const UnsafeBufferUsageHandler *,
Handler) {
- return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc());
+ if (Finder->getASTContext().getLangOpts().CPlusPlus)
+ return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc());
+ return true; /* Only warn about libc calls for C++ */
}
AST_MATCHER_P(CastExpr, castSubExpr, internal::Matcher<Expr>, innerMatcher) {
@@ -789,7 +791,7 @@ AST_MATCHER_P(CallExpr, hasUnsafePrintfStringArg,
if (!FristParmTy->isPointerType())
return false; // possibly some user-defined printf function
- QualType FirstPteTy = (cast<PointerType>(FristParmTy))->getPointeeType();
+ QualType FirstPteTy = FristParmTy->getAs<PointerType>()->getPointeeType();
if (!Ctx.getFILEType()
.isNull() && //`FILE *` must be in the context if it is fprintf
@@ -865,7 +867,7 @@ AST_MATCHER(CallExpr, hasUnsafeSnprintfBuffer) {
if (!FirstParmTy->isPointerType())
return false; // Not an snprint
- QualType FirstPteTy = cast<PointerType>(FirstParmTy)->getPointeeType();
+ QualType FirstPteTy = FirstParmTy->getAs<PointerType>()->getPointeeType();
const Expr *Buf = Node.getArg(0), *Size = Node.getArg(1);
if (FirstPteTy.isConstQualified() || !Buf->getType()->isPointerType() ||
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 117b2c8bc57935..724b543cdf882c 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2549,6 +2549,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
// UnsafeBufferUsage analysis settings.
+ bool IsCXXLang = S.getLangOpts().CPlusPlus;
bool UnsafeBufferUsageCanEmitSuggestions = S.getLangOpts().CPlusPlus20;
bool UnsafeBufferUsageShouldEmitSuggestions = // Should != Can.
UnsafeBufferUsageCanEmitSuggestions &&
@@ -2567,8 +2568,9 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
Node->getBeginLoc()) ||
!Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container,
Node->getBeginLoc()) ||
- !Diags.isIgnored(diag::warn_unsafe_buffer_libc_call,
- Node->getBeginLoc())) {
+ (!Diags.isIgnored(diag::warn_unsafe_buffer_libc_call,
+ Node->getBeginLoc()) &&
+ IsCXXLang /* we only warn about libc calls in C++ files */)) {
clang::checkUnsafeBufferUsage(Node, R,
UnsafeBufferUsageShouldEmitSuggestions);
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-no-libc-functions-in-c.c b/clang/test/SemaCXX/warn-unsafe-buffer-usage-no-libc-functions-in-c.c
new file mode 100644
index 00000000000000..e305c3e140dff9
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-no-libc-functions-in-c.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -Wunsafe-buffer-usage %s -verify %s
+
+void* memcpy(void *dst,const void *src, unsigned long size);
+
+void f(int *p, int *q) {
+
+ memcpy(p, q, 10); // no libc warn in C
+ ++p[5]; // expected-warning{{unsafe buffer access}}
+}
|
@llvm/pr-subscribers-clang Author: Ziqing Luo (ziqingluo-90) Changes
Full diff: https://github.com/llvm/llvm-project/pull/109496.diff 3 Files Affected:
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index a16762244b1766..110a121e71a7d2 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -250,7 +250,9 @@ AST_MATCHER_P(Stmt, ignoreUnsafeBufferInContainer,
AST_MATCHER_P(Stmt, ignoreUnsafeLibcCall, const UnsafeBufferUsageHandler *,
Handler) {
- return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc());
+ if (Finder->getASTContext().getLangOpts().CPlusPlus)
+ return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc());
+ return true; /* Only warn about libc calls for C++ */
}
AST_MATCHER_P(CastExpr, castSubExpr, internal::Matcher<Expr>, innerMatcher) {
@@ -789,7 +791,7 @@ AST_MATCHER_P(CallExpr, hasUnsafePrintfStringArg,
if (!FristParmTy->isPointerType())
return false; // possibly some user-defined printf function
- QualType FirstPteTy = (cast<PointerType>(FristParmTy))->getPointeeType();
+ QualType FirstPteTy = FristParmTy->getAs<PointerType>()->getPointeeType();
if (!Ctx.getFILEType()
.isNull() && //`FILE *` must be in the context if it is fprintf
@@ -865,7 +867,7 @@ AST_MATCHER(CallExpr, hasUnsafeSnprintfBuffer) {
if (!FirstParmTy->isPointerType())
return false; // Not an snprint
- QualType FirstPteTy = cast<PointerType>(FirstParmTy)->getPointeeType();
+ QualType FirstPteTy = FirstParmTy->getAs<PointerType>()->getPointeeType();
const Expr *Buf = Node.getArg(0), *Size = Node.getArg(1);
if (FirstPteTy.isConstQualified() || !Buf->getType()->isPointerType() ||
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 117b2c8bc57935..724b543cdf882c 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2549,6 +2549,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
// UnsafeBufferUsage analysis settings.
+ bool IsCXXLang = S.getLangOpts().CPlusPlus;
bool UnsafeBufferUsageCanEmitSuggestions = S.getLangOpts().CPlusPlus20;
bool UnsafeBufferUsageShouldEmitSuggestions = // Should != Can.
UnsafeBufferUsageCanEmitSuggestions &&
@@ -2567,8 +2568,9 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
Node->getBeginLoc()) ||
!Diags.isIgnored(diag::warn_unsafe_buffer_usage_in_container,
Node->getBeginLoc()) ||
- !Diags.isIgnored(diag::warn_unsafe_buffer_libc_call,
- Node->getBeginLoc())) {
+ (!Diags.isIgnored(diag::warn_unsafe_buffer_libc_call,
+ Node->getBeginLoc()) &&
+ IsCXXLang /* we only warn about libc calls in C++ files */)) {
clang::checkUnsafeBufferUsage(Node, R,
UnsafeBufferUsageShouldEmitSuggestions);
}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-no-libc-functions-in-c.c b/clang/test/SemaCXX/warn-unsafe-buffer-usage-no-libc-functions-in-c.c
new file mode 100644
index 00000000000000..e305c3e140dff9
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-no-libc-functions-in-c.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -Wunsafe-buffer-usage %s -verify %s
+
+void* memcpy(void *dst,const void *src, unsigned long size);
+
+void f(int *p, int *q) {
+
+ memcpy(p, q, 10); // no libc warn in C
+ ++p[5]; // expected-warning{{unsafe buffer access}}
+}
|
- Fix a bug in UnsafeBufferUsage.cpp related to casting to PointerType - Suppress -Wunsafe-buffer-usage-in-libc-call for C files (rdar://117182250)
e261352
to
e7f7f82
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to add some tests with annotated pointers to verify that you treat them correctly, e.g. _Nullable
@@ -789,7 +791,7 @@ AST_MATCHER_P(CallExpr, hasUnsafePrintfStringArg, | |||
if (!FristParmTy->isPointerType()) | |||
return false; // possibly some user-defined printf function | |||
|
|||
QualType FirstPteTy = (cast<PointerType>(FristParmTy))->getPointeeType(); | |||
QualType FirstPteTy = FristParmTy->getAs<PointerType>()->getPointeeType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: FristParmTy -> FirstParmTy
@@ -0,0 +1,9 @@ | |||
// RUN: %clang_cc1 -Wunsafe-buffer-usage %s -verify %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW the language mode is set via -x
command line option. It is only inferred from the file extension if -x
is missing.
return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc()); | ||
if (Finder->getASTContext().getLangOpts().CPlusPlus) | ||
return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc()); | ||
return true; /* Only warn about libc calls for C++ */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation should warn in Obj-C++ too and it should not in Obj-C but you might want to test that.
@@ -2549,6 +2549,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( | |||
DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions(); | |||
|
|||
// UnsafeBufferUsage analysis settings. | |||
bool IsCXXLang = S.getLangOpts().CPlusPlus; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: it doesn't feel like we need a variable for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments but LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
return false; // possibly some user-defined printf function | ||
|
||
QualType FirstPteTy = (cast<PointerType>(FristParmTy))->getPointeeType(); | ||
QualType FirstPteTy = FirstParmTy->getAs<PointerType>()->getPointeeType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
castAs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference between castAs
and getAs
is that castAs
asserts the canonical type is PointerType
while getAs
returns null if not. I think castAs
is more suitable for our case.
…les (llvm#109496) - Fix a bug in UnsafeBufferUsage.cpp related to casting to PointerType - Suppress -Wunsafe-buffer-usage-in-libc-call for C files (rdar://117182250) (cherry picked from commit 090dc77)