25 Commits

Author SHA1 Message Date
Oliver Stannard
0b0a37e158
[clang] Lifetime of locals must end before musttail call (#109255)
The lifetimes of local variables and function parameters must end before
the call to a [[clang::musttail]] function, instead of before the
return, because we will not have a stack frame to hold them when doing
the call.

This documents this limitation, and adds diagnostics to warn about some
code which is invalid because of it.
2024-09-23 10:04:08 +01:00
Haojian Wu
abe964aa47
[clang] Don't emit bogus dangling diagnostics when [[gsl::Owner]] and [[clang::lifetimebound]] are used together. (#108280)
In the GSL analysis, we don't track the `this` object if the conversion
is not from gsl::owner to gsl pointer, we want to be conservative here
to avoid triggering false positives.

Fixes #108272
2024-09-16 15:21:33 +02:00
Haojian Wu
0683c4e839 Revert "[clang] Diagnose dangling issues for the "Container<GSLPointer>" case. (#107213)"
This reverts commit e50131aa068f74daa70d4135c92020aadae3af33.

It introduces a new false positive, see comment https://github.com/llvm/llvm-project/pull/107213#issuecomment-2345465256
2024-09-12 09:24:32 +02:00
yronglin
060137038a
Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#108039)
The PR reapply https://github.com/llvm/llvm-project/pull/97308. 

- Implement [CWG1815](https://wg21.link/CWG1815): Support lifetime
extension of temporary created by aggregate initialization using a
default member initializer.

- Fix crash that introduced in
https://github.com/llvm/llvm-project/pull/97308. In
`InitListChecker::FillInEmptyInitForField`, when we enter
rebuild-default-init context, we copy all the contents of the parent
context to the current context, which will cause the `MaybeODRUseExprs`
to be lost. But we don't need to copy the entire context, only the
`DelayedDefaultInitializationContext` was required, which is used to
build `SourceLocExpr`, etc.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-09-12 06:29:48 +08:00
Haojian Wu
e50131aa06
[clang] Diagnose dangling issues for the "Container<GSLPointer>" case. (#107213)
This pull request enhances the GSL lifetime analysis to detect
situations where a dangling `Container<GSLPointer>` object is
constructed:

```cpp
std::vector<std::string_view> bad = {std::string()}; // dangling
```

The assignment case is not yet supported, but they will be addressed in
a follow-up.

Fixes #100526 (excluding the `push_back` case).
2024-09-11 13:20:59 +02:00
Martin Storsjö
cca54e347a Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#97308)"
This reverts commit 45c8766973bb3bb73dd8d996231e114dcf45df9f
and 049512e39d96995cb373a76cf2d009a86eaf3aab.

This change triggers failed asserts on inputs like this:

    struct a {
    } constexpr b;
    class c {
    public:
      c(a);
    };
    class B {
    public:
      using d = int;
      struct e {
        enum { f } g;
        int h;
        c i;
        d j{};
      };
    };
    B::e k{B::e::f, int(), b};

Compiled like this:

    clang -target x86_64-linux-gnu -c repro.cpp
    clang: ../../clang/lib/CodeGen/CGExpr.cpp:3105: clang::CodeGen::LValue
    clang::CodeGen::CodeGenFunction::EmitDeclRefLValue(const clang::DeclRefExpr*):
    Assertion `(ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
    !E->getLocation().isValid()) && "Should not use decl without marking it used!"' failed.
2024-09-09 15:09:45 +03:00
yronglin
45c8766973
Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#97308)
The PR reapply https://github.com/llvm/llvm-project/pull/92527.
Implemented CWG1815 and fixed the bugs mentioned in the comments of
https://github.com/llvm/llvm-project/pull/92527 and
https://github.com/llvm/llvm-project/pull/87933.

The reason why the original PR was reverted was that errors might occur
during the rebuild.

---------

Signed-off-by: yronglin <yronglin777@gmail.com>
2024-09-08 22:36:49 +08:00
Haojian Wu
a918fa117a
[clang] Emit -Wdangling diagnoses for cases where a gsl-pointer is construct from a gsl-owner object in a container. (#104556)
The warning is not emitted for the case `string_view c =
std::vector<std::string>({""}).at(0);` because we bail out during the
visit of the LHS at [this
point](5d2c324fea/clang/lib/Sema/CheckExprLifetime.cpp (L341-L343))
in the code.

This bailout was introduced in [this
commit](bcd0798c47)
to address a false positive with
`vector<vector::iterator>({""}).at(0);`. This PR refines that fix by
ensuring that, for initialization involving a gsl-pointer, we only
consider constructor calls that take the gsl-owner object.

Fixes #100384.
2024-09-06 12:37:21 +02:00
Haojian Wu
3e070906ef Fix llvm-else-after-return clang-tidy warning in CheckExprLifetime.cpp, NFC 2024-09-05 13:24:38 +02:00
Haojian Wu
87b4b64858 Fix a typo in CheckExprLifetime.cpp, NFC 2024-09-05 13:18:39 +02:00
Haojian Wu
d94199c8ff
[clang] Make lifetimebound and GSL analysis more coherent (#105884)
This allows clang to detect more use-after-free bugs (shown in the
#100549).

This relands the remaining change (removing the EnableLifetimeWarnings
flag) in https://github.com/llvm/llvm-project/pull/104906, with a proper
fix for the regression.

Fixes #100549
2024-09-04 13:49:48 +02:00
Haojian Wu
01e5684900
[clang] Respect the lifetimebound in assignment operator. (#106997)
Fixes #106372
2024-09-04 10:09:04 +02:00
Haojian Wu
7b2fe84ff5 Don't run the lifetime analysis for pointer assignment if the warning is
disabled.
2024-09-01 16:19:18 +02:00
Haojian Wu
b1560bdb2b
Reland "[clang] Merge lifetimebound and GSL code paths for lifetime analysis (#104906)" (#105838)
Reland without the `EnableLifetimeWarnings` removal. I will remove the
EnableLifetimeWarnings in a follow-up patch.

I have added a test to prevent regression.
2024-08-23 17:50:27 +02:00
Vitaly Buka
1df15042bd
Revert "[clang] Merge lifetimebound and GSL code paths for lifetime analysis (#104906)" (#105752)
Revert as it breaks libc++ tests, see #104906.

This reverts commit c368a720a0b40bb8fe4aff3971fe9a7009c85aa6.
2024-08-22 16:38:19 -07:00
Haojian Wu
c368a720a0
[clang] Merge lifetimebound and GSL code paths for lifetime analysis (#104906)
In the current lifetime analysis, we have two parallel code paths: one
for lifetimebound and another for GSL. These paths perform the same
logic, both determining whether to continue visiting subexpressions.

This PR merges the two paths into a single code path. As a result, we'll
reduce the overhead by eliminating a redundant visit to subexpressions.
The change is mostly NFC (No Functional Change). The only notable
difference is that when a subexpression is visited due to either
lifetimebound or GSL, we will prioritize the lifetimebound path. This
means the final diagnostic will be -Wdangling (rather than both
`-Wdangling` and `-Wdangling-gsl`)

This might cause a slight change in behavior if the -Wdangling
diagnostic is disabled, but I think this is not a major concern since
both diagnostics are enabled by default.

Fixes #93386
2024-08-22 10:35:49 +02:00
Haojian Wu
5d2c324fea Remove a leftover debug-only statement in CheckExprLifetime.cpp 2024-07-29 09:22:03 +02:00
Utkarsh Saxena
1feef92a77
Fix lifetimebound for field access (#100197)
Fixes: https://github.com/llvm/llvm-project/issues/81589

There is no way to switch this off without  `-Wno-dangling`.
2024-07-24 15:58:52 +02:00
Haojian Wu
71e2b8df30
[clang] NFC, simplify the code in CheckExprLifetime.cpp (#99637)
No need to get the Owner/Pointer attr via the type. The Decl has this
attr information.
2024-07-19 16:46:31 +02:00
Haojian Wu
3eba28d1fd
[clang] Extend lifetime analysis to support assignments for pointer-like objects. (#99032)
This is a follow-up patch to #96475 to detect dangling assignments for
C++ pointer-like objects (classes annotated with the
`[[gsl::Pointer]]`). Fixes #63310.

Similar to the behavior for built-in pointer types, if a temporary owner
(`[[gsl::Owner]]`) object is assigned to a pointer-like class object,
and this temporary object is destroyed at the end of the full assignment
expression, the assignee pointer is considered dangling. In such cases,
clang will emit a warning:

```
/tmp/t.cpp:7:20: warning: object backing the pointer my_string_view will be destroyed at the end of the full-expression [-Wdangling-assignment-gsl]
    7 |   my_string_view = CreateString();
      |                    ^~~~~~~~~~~~~~
1 warning generated.
```

This new warning is `-Wdangling-assignment-gsl`. It is initially
disabled, but I intend to enable it by default in clang 20.

I have initially tested this patch on our internal codebase, and it has
identified many use-after-free bugs, primarily related to `string_view`.
2024-07-18 10:02:35 +02:00
Haojian Wu
c30ce8b9d3
[clang] Refactor: Introduce a new LifetimeKind for the assignment case, NFC (#99005)
The current implementation for the assignment case uses a combination of
the `LK_Extended` lifetime kind and the validity of `AEntity`, which is
somewhat messy and doesn't align well with the intended mental model.

This patch introduces a dedicated lifetime kind to handle the assignment
case, simplifying the implementation and improving clarity.
2024-07-16 11:23:39 +02:00
Haojian Wu
c3079ffcd3
[clang] Don't emit the warn_dangling_lifetime_pointer diagnostic for the assignment case. (#97408)
The `lifetime_pointer` case is handled before the assignment case. In
scenarios where we have the `gsl::Pointer` attribute, we may emit the
`-Wdangling-gsl` warning for assignment cases. This means we cannot use
`-Wno-dangling-assignment` to suppress the newly-added warning, this
patch fixes it.
2024-07-02 15:21:06 +02:00
Gábor Horváth
ffca4ef5b1
[clang] Remove a pointer union from the lifetime bound analysis (#97327)
Since all callers of the API is called with the same type, we do not
actually need the pointer union.
2024-07-01 23:56:59 +01:00
Haojian Wu
5c287efee7
[Clang] Extend lifetime bound analysis to support assignments for the built-in pointer type (#96475)
The lifetime bound warning in Clang currently only considers
initializations. This patch extends the warning to include assignments.

- **Support for assignments of built-in pointer types**: this is done is
by reusing the existing statement-local implementation. Clang now warns
if the pointer is assigned to a temporary object that being destoryed at
the end of the full assignment expression.

With this patch, we will detect more cases under the on-by-default
diagnostic `-Wdangling`. I have added a new category for this specific
diagnostic so that people can temporarily disable it if their codebase
is not yet clean.

This is the first step to address #63310, focusing only on pointer
types. Support for C++ assignment operators will come in a follow-up
patch.

Fixes #54492
2024-07-01 17:43:07 +02:00
Haojian Wu
8a43dc3efd
[clang][Sema] Move the initializer lifetime checking code from SemaInit.cpp to a new place, NFC (#96758)
This is a refactoring change for better code isolation and reuse, the
first step to extend it for assignments.
2024-06-27 10:56:06 +02:00