-
Notifications
You must be signed in to change notification settings - Fork 14.1k
[NFC][Clang] Avoid potential null pointer dereferences in Sema::AddInitializerToDecl(). #106235
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
[NFC][Clang] Avoid potential null pointer dereferences in Sema::AddInitializerToDecl(). #106235
Conversation
…itializerToDecl(). Control flow analysis performed by a static analysis tool revealed the potential for null pointer dereferences to occur in conjunction with the `Init` parameter in Sema::AddInitializerToDecl(). On entry to the function, `Init` is required to be non-null as there are multiple potential branches that unconditionally dereference it. However, there were two places where `Init` is compared to null thus implying that `Init` is expected to be null in some cases. These checks appear to be purely defensive checks and thus unnecessary. Further, there were several cases where code checked `Result`, a variable of type `ExprResult`, for an invalid value, but did not check for a valid but null value and then proceeded to unconditionally dereference the potential null result. This change elides the unnecessary defensive checks and changes some checks for an invalid result to instead branch on an unusable result (either an invalid result or a valid but null result).
@llvm/pr-subscribers-clang Author: Tom Honermann (tahonermann) ChangesControl flow analysis performed by a static analysis tool revealed the potential for null pointer dereferences to occur in conjunction with the Full diff: https://github.com/llvm/llvm-project/pull/106235.diff 1 Files Affected:
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index b0ccbbe34b70c3..c643d4fbbba0eb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13319,7 +13319,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
}
// WebAssembly tables can't be used to initialise a variable.
- if (Init && !Init->getType().isNull() &&
+ if (!Init->getType().isNull() &&
Init->getType()->isWebAssemblyTableType()) {
Diag(Init->getExprLoc(), diag::err_wasm_table_art) << 0;
VDecl->setInvalidDecl();
@@ -13463,7 +13463,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
if (getLangOpts().DebuggerCastResultToId && DclT->isObjCObjectPointerType() &&
Init->getType() == Context.UnknownAnyTy) {
ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType());
- if (Result.isInvalid()) {
+ if (!Result.isUsable()) {
VDecl->setInvalidDecl();
return;
}
@@ -13491,7 +13491,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E));
return Init.Failed() ? ExprError() : E;
});
- if (Res.isInvalid()) {
+ if (!Res.isUsable()) {
VDecl->setInvalidDecl();
} else if (Res.get() != Args[Idx]) {
Args[Idx] = Res.get();
@@ -13504,7 +13504,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
/*TopLevelOfInitList=*/false,
/*TreatUnavailableAsInvalid=*/false);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
- if (Result.isInvalid()) {
+ if (!Result.isUsable()) {
// If the provided initializer fails to initialize the var decl,
// we attach a recovery expr for better recovery.
auto RecoveryExpr =
@@ -13528,7 +13528,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
InitSeq.step_begin()->Kind ==
InitializationSequence::SK_ParenthesizedListInit;
QualType VDeclType = VDecl->getType();
- if (Init && !Init->getType().isNull() &&
+ if (!Init->getType().isNull() &&
!Init->getType()->isDependentType() && !VDeclType->isDependentType() &&
Context.getAsIncompleteArrayType(VDeclType) &&
Context.getAsIncompleteArrayType(Init->getType())) {
@@ -13592,7 +13592,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
ExprResult Result =
ActOnFinishFullExpr(Init, VDecl->getLocation(),
/*DiscardedValue*/ false, VDecl->isConstexpr());
- if (Result.isInvalid()) {
+ if (!Result.isUsable()) {
VDecl->setInvalidDecl();
return;
}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
See #94368 for a prior attempt to address this static analysis concern. |
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, thanks!
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!
Control flow analysis performed by a static analysis tool revealed the potential for null pointer dereferences to occur in conjunction with the
Init
parameter inSema::AddInitializerToDecl()
. On entry to the function,Init
is required to be non-null as there are multiple potential branches that unconditionally dereference it. However, there were two places whereInit
is compared to null thus implying thatInit
is expected to be null in some cases. These checks appear to be purely defensive checks and thus unnecessary. Further, there were several cases where code checkedResult
, a variable of typeExprResult
, for an invalid value, but did not check for a valid but null value and then proceeded to unconditionally dereference the potential null result. This change elides the unnecessary defensive checks and changes some checks for an invalid result to instead branch on an unusable result (either an invalid result or a valid but null result).