[clang] [clang][Sema] Warn on return of pointer/reference to compound literal (PR #83741)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 3 12:20:18 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Youngsuk Kim (JOE1994)
<details>
<summary>Changes</summary>
Emit a warning if pointer/reference to compound literal is returned from a function.
In C, compound literals in block scope are lvalues that have automatic storage duration. In C++, compound literals in block scope are temporaries.
In either case, returning a pointer/reference to a compound literal can cause a use-after-free bug.
Fixes #<!-- -->8678
---
Full diff: https://github.com/llvm/llvm-project/pull/83741.diff
3 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+1-1)
- (modified) clang/lib/Sema/SemaInit.cpp (+12)
- (modified) clang/test/Analysis/stack-addr-ps.c (+2-2)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 91105d4231f06a..f5c88b8ae5aade 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9898,7 +9898,7 @@ def err_lifetimebound_ctor_dtor : Error<
// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr_ref : Warning<
"%select{address of|reference to}0 stack memory associated with "
- "%select{local variable|parameter}2 %1 returned">,
+ "%select{local variable|parameter|compound literal}2 %1 returned">,
InGroup<ReturnStackAddress>;
def warn_ret_local_temp_addr_ref : Warning<
"returning %select{address of|reference to}0 local temporary object">,
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 0fd458837163e5..93b125382b164f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7734,6 +7734,14 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
break;
}
+ case Stmt::CompoundLiteralExprClass: {
+ if (auto *CLE = dyn_cast<CompoundLiteralExpr>(Init)) {
+ if (!CLE->isFileScope())
+ Visit(Path, Local(CLE), RK);
+ }
+ break;
+ }
+
// FIXME: Visit the left-hand side of an -> or ->*.
default:
@@ -8289,6 +8297,10 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity,
if (LK == LK_StmtExprResult)
return false;
Diag(DiagLoc, diag::warn_ret_addr_label) << DiagRange;
+ } else if (auto *CLE = dyn_cast<CompoundLiteralExpr>(L)) {
+ Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
+ << Entity.getType()->isReferenceType() << CLE->getInitializer() << 2
+ << DiagRange;
} else {
Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref)
<< Entity.getType()->isReferenceType() << DiagRange;
diff --git a/clang/test/Analysis/stack-addr-ps.c b/clang/test/Analysis/stack-addr-ps.c
index 26e1cc58350cab..e469396e1bb22a 100644
--- a/clang/test/Analysis/stack-addr-ps.c
+++ b/clang/test/Analysis/stack-addr-ps.c
@@ -20,13 +20,13 @@ int* f3(int x, int *y) {
void* compound_literal(int x, int y) {
if (x)
- return &(unsigned short){((unsigned short)0x22EF)}; // expected-warning{{Address of stack memory}}
+ return &(unsigned short){((unsigned short)0x22EF)}; // expected-warning{{Address of stack memory}} expected-warning{{address of stack memory}}
int* array[] = {};
struct s { int z; double y; int w; };
if (y)
- return &((struct s){ 2, 0.4, 5 * 8 }); // expected-warning{{Address of stack memory}}
+ return &((struct s){ 2, 0.4, 5 * 8 }); // expected-warning{{Address of stack memory}} expected-warning{{address of stack memory}}
void* p = &((struct s){ 42, 0.4, x ? 42 : 0 });
``````````
</details>
https://github.com/llvm/llvm-project/pull/83741
More information about the cfe-commits
mailing list