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 }); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits