[clang] 9dab2e3 - [clang][Sema] Warn on return of pointer/reference to compound literal (#83741)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 4 19:10:24 PST 2024
Author: Youngsuk Kim
Date: 2024-03-04T22:10:20-05:00
New Revision: 9dab2e3064a2ad4d5ce65832d605787dc394cb72
URL: https://github.com/llvm/llvm-project/commit/9dab2e3064a2ad4d5ce65832d605787dc394cb72
DIFF: https://github.com/llvm/llvm-project/commit/9dab2e3064a2ad4d5ce65832d605787dc394cb72.diff
LOG: [clang][Sema] Warn on return of pointer/reference to compound literal (#83741)
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
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaInit.cpp
clang/test/Analysis/stack-addr-ps.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8ea194ceadb5d1..b50a4895e171b5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9901,7 +9901,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 });
More information about the cfe-commits
mailing list