Skip to content

[clang-tidy] ignore [[clang::lifetimebound]] param in return-const-ref-from-parameter #118315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "ReturnConstRefFromParameterCheck.h"
#include "clang/AST/Attrs.inc"
#include "clang/AST/Expr.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
Expand All @@ -15,14 +16,23 @@ using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

namespace {

AST_MATCHER(ParmVarDecl, hasLifetimeBoundAttr) {
return Node.hasAttr<LifetimeBoundAttr>();
}

} // namespace

void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) {
const auto DRef = ignoringParens(
declRefExpr(
to(parmVarDecl(hasType(hasCanonicalType(
qualType(lValueReferenceType(pointee(
qualType(isConstQualified()))))
.bind("type"))),
hasDeclContext(functionDecl().bind("owner")))
hasDeclContext(functionDecl().bind("owner")),
unless(hasLifetimeBoundAttr()))
.bind("param")))
.bind("dref"));
const auto Func =
Expand Down
3 changes: 2 additions & 1 deletion clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ Changes in existing checks
<clang-tidy/checks/bugprone/return-const-ref-from-parameter>` check to
diagnose potential dangling references when returning a ``const &`` parameter
by using the conditional operator ``cond ? var1 : var2`` and no longer giving
false positives for functions which contain lambda.
false positives for functions which contain lambda and ignore parameters
with ``[[clang::lifetimebound]]`` attribute.

- Improved :doc:`bugprone-sizeof-expression
<clang-tidy/checks/bugprone/sizeof-expression>` check to find suspicious
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,6 @@ after the call. When the function returns such a parameter also as constant refe
then the returned reference can be used after the object it refers to has been
destroyed.

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

Example
-------

Expand All @@ -38,3 +29,23 @@ Example

const S& s = fn(S{1});
s.v; // use after free


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

This issue can also be resolved by adding ``[[clang::lifetimebound]]``. Clang
enable ``-Wdangling`` warning by default which can detect mis-uses of the
annotated function. See `lifetimebound attribute <https://clang.llvm.org/docs/AttributeReference.html#id11>`_
for details.

.. code-block:: c++

const int &f(const int &a [[clang::lifetimebound]]) { return a; } // no warning
const int &v = f(1); // warning: temporary bound to local reference 'v' will be destroyed at the end of the full-expression [-Wdangling]
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,9 @@ int const &overload_params_difference3(int p1, int const &a, int p2) { return a;
int const &overload_params_difference3(int p1, long &&a, int p2);

} // namespace overload

namespace gh117696 {
namespace use_lifetime_bound_attr {
int const &f(int const &a [[clang::lifetimebound]]) { return a; }
} // namespace use_lifetime_bound_attr
} // namespace gh117696
Loading