https://github.com/JOE1994 created https://github.com/llvm/llvm-project/pull/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 >From fc0cb9c44ec7945f1a88420675b667167908e07c Mon Sep 17 00:00:00 2001 From: JOE1994 <joseph942...@gmail.com> Date: Sun, 3 Mar 2024 12:38:49 -0500 Subject: [PATCH] [clang][Sema] Warn on return of pointer/reference to compound literal 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. --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaInit.cpp | 12 ++++++++++++ clang/test/Analysis/stack-addr-ps.c | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) 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 }); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits