Skip to content

Commit 57907c1

Browse files
authored
[clang-tidy] ignore [[clang::lifetimebound]] param in return-const-ref-from-parameter (llvm#118315)
Fixed llvm#117696
1 parent 8c749ff commit 57907c1

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "ReturnConstRefFromParameterCheck.h"
10+
#include "clang/AST/Attrs.inc"
1011
#include "clang/AST/Expr.h"
1112
#include "clang/ASTMatchers/ASTMatchFinder.h"
1213
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -15,14 +16,23 @@ using namespace clang::ast_matchers;
1516

1617
namespace clang::tidy::bugprone {
1718

19+
namespace {
20+
21+
AST_MATCHER(ParmVarDecl, hasLifetimeBoundAttr) {
22+
return Node.hasAttr<LifetimeBoundAttr>();
23+
}
24+
25+
} // namespace
26+
1827
void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) {
1928
const auto DRef = ignoringParens(
2029
declRefExpr(
2130
to(parmVarDecl(hasType(hasCanonicalType(
2231
qualType(lValueReferenceType(pointee(
2332
qualType(isConstQualified()))))
2433
.bind("type"))),
25-
hasDeclContext(functionDecl().bind("owner")))
34+
hasDeclContext(functionDecl().bind("owner")),
35+
unless(hasLifetimeBoundAttr()))
2636
.bind("param")))
2737
.bind("dref"));
2838
const auto Func =

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ Changes in existing checks
184184
<clang-tidy/checks/bugprone/return-const-ref-from-parameter>` check to
185185
diagnose potential dangling references when returning a ``const &`` parameter
186186
by using the conditional operator ``cond ? var1 : var2`` and no longer giving
187-
false positives for functions which contain lambda.
187+
false positives for functions which contain lambda and ignore parameters
188+
with ``[[clang::lifetimebound]]`` attribute.
188189

189190
- Improved :doc:`bugprone-sizeof-expression
190191
<clang-tidy/checks/bugprone/sizeof-expression>` check to find suspicious

clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,6 @@ after the call. When the function returns such a parameter also as constant refe
1212
then the returned reference can be used after the object it refers to has been
1313
destroyed.
1414

15-
This issue can be resolved by declaring an overload of the problematic function
16-
where the ``const &`` parameter is instead declared as ``&&``. The developer has
17-
to ensure that the implementation of that function does not produce a
18-
use-after-free, the exact error that this check is warning against.
19-
Marking such an ``&&`` overload as ``deleted``, will silence the warning as
20-
well. In the case of different ``const &`` parameters being returned depending
21-
on the control flow of the function, an overload where all problematic
22-
``const &`` parameters have been declared as ``&&`` will resolve the issue.
23-
2415
Example
2516
-------
2617

@@ -38,3 +29,23 @@ Example
3829

3930
const S& s = fn(S{1});
4031
s.v; // use after free
32+
33+
34+
This issue can be resolved by declaring an overload of the problematic function
35+
where the ``const &`` parameter is instead declared as ``&&``. The developer has
36+
to ensure that the implementation of that function does not produce a
37+
use-after-free, the exact error that this check is warning against.
38+
Marking such an ``&&`` overload as ``deleted``, will silence the warning as
39+
well. In the case of different ``const &`` parameters being returned depending
40+
on the control flow of the function, an overload where all problematic
41+
``const &`` parameters have been declared as ``&&`` will resolve the issue.
42+
43+
This issue can also be resolved by adding ``[[clang::lifetimebound]]``. Clang
44+
enable ``-Wdangling`` warning by default which can detect mis-uses of the
45+
annotated function. See `lifetimebound attribute <https://clang.llvm.org/docs/AttributeReference.html#id11>`_
46+
for details.
47+
48+
.. code-block:: c++
49+
50+
const int &f(const int &a [[clang::lifetimebound]]) { return a; } // no warning
51+
const int &v = f(1); // warning: temporary bound to local reference 'v' will be destroyed at the end of the full-expression [-Wdangling]

clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,9 @@ int const &overload_params_difference3(int p1, int const &a, int p2) { return a;
197197
int const &overload_params_difference3(int p1, long &&a, int p2);
198198

199199
} // namespace overload
200+
201+
namespace gh117696 {
202+
namespace use_lifetime_bound_attr {
203+
int const &f(int const &a [[clang::lifetimebound]]) { return a; }
204+
} // namespace use_lifetime_bound_attr
205+
} // namespace gh117696

0 commit comments

Comments
 (0)