From 4862febdce572e6952b02283a6c7e53617e3aac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Thu, 21 Nov 2024 23:25:37 +0000 Subject: [PATCH] [clang][APINotes] Do not add duplicate lifetimebound annotations (#117194) In case a method already is lifetimebound annotated we should not add a second annotation to the type. --- clang/lib/Sema/CheckExprLifetime.cpp | 2 +- clang/lib/Sema/CheckExprLifetime.h | 2 ++ clang/lib/Sema/SemaAPINotes.cpp | 4 +++- clang/test/APINotes/Inputs/Headers/Lifetimebound.apinotes | 4 ++++ clang/test/APINotes/Inputs/Headers/Lifetimebound.h | 1 + clang/test/APINotes/lifetimebound.cpp | 1 + 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 8886e5e307dd..182ac806d3c1 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -498,7 +498,7 @@ static bool isNormalAssignmentOperator(const FunctionDecl *FD) { return false; } -static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { +bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { const TypeSourceInfo *TSI = FD->getTypeSourceInfo(); if (!TSI) return false; diff --git a/clang/lib/Sema/CheckExprLifetime.h b/clang/lib/Sema/CheckExprLifetime.h index 38b7061988dc..b10c84363527 100644 --- a/clang/lib/Sema/CheckExprLifetime.h +++ b/clang/lib/Sema/CheckExprLifetime.h @@ -57,6 +57,8 @@ void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, void checkExprLifetimeMustTailArg(Sema &SemaRef, const InitializedEntity &Entity, Expr *Init); +bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD); + } // namespace clang::sema #endif // LLVM_CLANG_SEMA_CHECK_EXPR_LIFETIME_H diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index cbc092195ad3..028bf82f3e80 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "CheckExprLifetime.h" #include "TypeLocBuilder.h" #include "clang/APINotes/APINotesReader.h" #include "clang/AST/Decl.h" @@ -568,7 +569,8 @@ static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc, static void ProcessAPINotes(Sema &S, CXXMethodDecl *Method, const api_notes::CXXMethodInfo &Info, VersionedInfoMetadata Metadata) { - if (Info.This && Info.This->isLifetimebound()) { + if (Info.This && Info.This->isLifetimebound() && + !sema::implicitObjectParamIsLifetimeBound(Method)) { auto MethodType = Method->getType(); auto *attr = ::new (S.Context) LifetimeBoundAttr(S.Context, getPlaceholderAttrInfo()); diff --git a/clang/test/APINotes/Inputs/Headers/Lifetimebound.apinotes b/clang/test/APINotes/Inputs/Headers/Lifetimebound.apinotes index 4bd5fbb42bf0..0cdd855c0a05 100644 --- a/clang/test/APINotes/Inputs/Headers/Lifetimebound.apinotes +++ b/clang/test/APINotes/Inputs/Headers/Lifetimebound.apinotes @@ -12,6 +12,10 @@ Tags: Parameters: - Position: -1 Lifetimebound: true + - Name: annotateThis2 + Parameters: + - Position: -1 + Lifetimebound: true - Name: methodToAnnotate Parameters: - Position: 0 diff --git a/clang/test/APINotes/Inputs/Headers/Lifetimebound.h b/clang/test/APINotes/Inputs/Headers/Lifetimebound.h index be0ed1494500..b8097c202d8d 100644 --- a/clang/test/APINotes/Inputs/Headers/Lifetimebound.h +++ b/clang/test/APINotes/Inputs/Headers/Lifetimebound.h @@ -3,5 +3,6 @@ int *funcToAnnotate(int *p); struct MyClass { MyClass(int*); int *annotateThis(); + int *annotateThis2() [[clang::lifetimebound]]; int *methodToAnnotate(int *p); }; diff --git a/clang/test/APINotes/lifetimebound.cpp b/clang/test/APINotes/lifetimebound.cpp index 3cdba0136a52..f6fdb8535b18 100644 --- a/clang/test/APINotes/lifetimebound.cpp +++ b/clang/test/APINotes/lifetimebound.cpp @@ -14,3 +14,4 @@ // CHECK-METHOD-NEXT: LifetimeBoundAttr // CHECK-METHOD-THIS: CXXMethodDecl {{.+}} annotateThis 'int *() {{\[\[}}clang::lifetimebound{{\]\]}}' +// CHECK-METHOD-THIS: CXXMethodDecl {{.+}} annotateThis2 'int *() {{\[\[}}clang::lifetimebound{{\]\]}}'