170 Commits

Author SHA1 Message Date
Utkarsh Saxena
498e1c2257
[coroutine] Create coroutine body in the correct eval context (#78589)
Fixes: https://github.com/llvm/llvm-project/issues/78290

See the bug for more context.
```cpp
Gen ACoroutine() {
  if constexpr (0) // remove it make clang compile.
    co_return;
  co_await Gen{};
}
```
We miss symbol of ctor of promise_type if the first coroutine statement
happens to be inside the disabled branch of `if constexpr`.

This happens because the promise object is built when we see the first
coroutine statement which is present in
`ExpressionEvaluationContext::DiscardedStatement` context due to `if
constexpr (0)`. This makes clang believe that the promise constructor is
only odr-used and not really "used".

The expr evaluation context for the coroutine body should not be related
to the context in which the first coroutine statement appears. We
override the context to `PotentiallyEvaluated`.

---------

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2024-01-19 08:23:25 +01:00
Utkarsh Saxena
667e58a72e
[coroutines][coro_lifetimebound] Detect lifetime issues with lambda captures (#77066)
### Problem

```cpp
co_task<int> coro() {
    int a = 1;
    auto lamb = [a]() -> co_task<int> {
        co_return a; // 'a' in the lambda object dies after the iniital_suspend in the lambda coroutine.
    }();
    co_return co_await lamb;
}
```
[use-after-free](https://godbolt.org/z/GWPEovWWc)

Lambda captures (even by value) are prone to use-after-free once the
lambda object dies. In the above example, the lambda object appears only
as a temporary in the call expression. It dies after the first
suspension (`initial_suspend`) in the lambda.
On resumption in `co_await lamb`, the lambda accesses `a` which is part
of the already-dead lambda object.

---

### Solution

This problem can be formulated by saying that the `this` parameter of
the lambda call operator is a lifetimebound parameter. The lambda object
argument should therefore live atleast as long as the return object.
That said, this requirement does not hold if the lambda does not have a
capture list. In principle, the coroutine frame still has a reference to
a dead lambda object, but it is easy to see that the object would not be
used in the lambda-coroutine body due to no capture list.

It is safe to use this pattern inside a`co_await` expression due to the
lifetime extension of temporaries. Example:

```cpp
co_task<int> coro() {
    int a = 1;
    int res = co_await [a]() -> co_task<int> { co_return a; }();
    co_return res;
}
```
---
### Background

This came up in the discussion with seastar folks on
[RFC](https://discourse.llvm.org/t/rfc-lifetime-bound-check-for-parameters-of-coroutines/74253/19?u=usx95).
This is a fairly common pattern in continuation-style-passing (CSP)
async programming involving futures and continuations. Document ["Lambda
coroutine
fiasco"](https://github.com/scylladb/seastar/blob/master/doc/lambda-coroutine-fiasco.md)
by Seastar captures the problem.
This pattern makes the migration from CSP-style async programming to
coroutines very bugprone.


Fixes https://github.com/llvm/llvm-project/issues/76995

---------

Co-authored-by: Chuanqi Xu <yedeng.yd@linux.alibaba.com>
2024-01-18 11:56:55 +01:00
Yuxuan Chen
858b56e496
[Clang] Preserve coroutine parameter referenced state (#70973)
This PR is proposing a fix for
https://github.com/llvm/llvm-project/issues/65971.

Previously, given a coroutine like this
```
task foo(int a) {
  co_return;
}
```
Parameter `a` is never used. However, because C++ coroutines move
constructs the variable to a heap allocated coroutine activation frame,
we considered all parameters referenced. When diagnosing unused
parameters, we cannot distinguish if the variable reference was due to
coroutine parameter moves.

Compiler Explorer shows that GCC warns against this case correctly, but
clang does not: https://godbolt.org/z/Wo7dfqeaf

This patch addresses this issue by preserving the original
`ParmVarDecl`'s `Referenced` state.
2023-11-02 14:03:47 +08:00
Vlad Serebrennikov
4ad2ada521 [clang][NFC] Refactor ElaboratedTypeKeyword
This patch moves ElaboratedTypeKeyword before `Type` definition so that the enum is complete where bit-field for it is declared. It also converts it to scoped enum and removes `ETK_` prefix.
2023-10-31 20:46:07 +03:00
Aaron Ballman
09e8ef975d
Diagnose use of VLAs in a coroutine (#70341)
Fixes https://github.com/llvm/llvm-project/issues/65858
2023-10-26 11:59:17 -04:00
Corentin Jabot
af4751738d [C++] Implement "Deducing this" (P0847R7)
This patch implements P0847R7 (partially),
CWG2561 and CWG2653.

Reviewed By: aaron.ballman, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D140828
2023-10-02 14:33:02 +02:00
Chris Bieneman
400d3261a0 [HLSL] Cleanup support for this as an l-value
The goal of this change is to clean up some of the code surrounding
HLSL using CXXThisExpr as a non-pointer l-value. This change cleans up
a bunch of assumptions and inconsistencies around how the type of
`this` is handled through the AST and code generation.

This change is be mostly NFC for HLSL, and completely NFC for other
language modes.

This change introduces a new member to query for the this object's type
and seeks to clarify the normal usages of the this type.

With the introudction of HLSL to clang, CXXThisExpr may now be an
l-value and behave like a reference type rather than C++'s normal
method of it being an r-value of pointer type.

With this change there are now three ways in which a caller might need
to query the type of `this`:

* The type of the `CXXThisExpr`
* The type of the object `this` referrs to
* The type of the implicit (or explicit) `this` argument

This change codifies those three ways you may need to query
respectively as:

* CXXMethodDecl::getThisType()
* CXXMethodDecl::getThisObjectType()
* CXXMethodDecl::getThisArgType()

This change then revisits all uses of `getThisType()`, and in cases
where the only use was to resolve the pointee type, it replaces the
call with `getThisObjectType()`. In other cases it evaluates whether
the desired returned type is the type of the `this` expr, or the type
of the `this` function argument. The `this` expr type is used for
creating additional expr AST nodes and for member lookup, while the
argument type is used mostly for code generation.

Additionally some cases that used `getThisType` in simple queries could
be substituted for `getThisObjectType`. Since `getThisType` is
implemented in terms of `getThisObjectType` calling the later should be
more efficient if the former isn't needed.

Reviewed By: aaron.ballman, bogner

Differential Revision: https://reviews.llvm.org/D159247
2023-09-05 19:38:50 -05:00
Chuanqi Xu
20e6515d5c [Coroutines] Mark 'coroutine_handle<>::address' as always-inline
Close https://github.com/llvm/llvm-project/issues/65054

The direct issue is still the call to coroutine_handle<>::address()
after await_suspend(). Without optimizations, the current logic will put
the temporary result of await_suspend() to the coroutine frame since the
middle end feel the temporary is escaped from
coroutine_handle<>::address. To fix this fundamentally, we should wrap
the whole logic about await-suspend into a standalone function. See
https://github.com/llvm/llvm-project/issues/64945

And as a short-term workaround, we probably can mark
coroutine_handle<>::address() as always-inline so that the temporary
result may not be thought to be escaped then it won't be put on the
coroutine frame. Although it looks dirty, it is probably do-able since
the compiler are allowed to do special tricks to standard library
components.
2023-08-29 14:35:27 +08:00
Chuanqi Xu
b32aa72afc Recommit [C++20] [Coroutines] Mark await_suspend as noinline if the awaiter is not empty
The original patch is incorrect since it marks too many calls to be
noinline. It shows that it is bad to do analysis in the frontend again.
This patch tries to mark the await_suspend function as noinlne only.

---

Close https://github.com/llvm/llvm-project/issues/56301
Close https://github.com/llvm/llvm-project/issues/64151
Close https://github.com/llvm/llvm-project/issues/65018

See the summary and the discussion of
https://reviews.llvm.org/D157070
to get the full context.

As @rjmccall pointed out, the key point of the root cause is that
currently we didn't implement the semantics for '@llvm.coro.save'
well ("after the await-ready returns false, the coroutine is considered
to be suspended ") well.
Since the semantics implies that we (the compiler) shouldn't write
the spills into the coroutine frame in the await_suspend. But now it is
possible due to some combinations of the optimizations so the semantics are
broken. And the inlining is the root optimization of such optimizations.
So in this patch, we tried to add the `noinline` attribute to the
await_suspend function.

This looks slightly problematic since the users are able to call the
await_suspend function standalone. This is limited by the
implementation. On the one hand, we don't want the workaround solution
(See the proposed solution later) to be too complex. On the other hand,
it is rare to call await_suspend standalone. Also it is not semantically
incorrect to do so since the inlining is not part of the C++ standard.

Also as an optimization, we don't add the `noinline` attribute to
the await_suspend function if the awaiter is an empty class. This should be
correct since the programmers can't access the local variables in
await_suspend if the awaiter is empty. I think this is necessary for
the performance since it is pretty common.

The long term solution is:

    call @llvm.coro.await_suspend(ptr %awaiter, ptr %handle,
                                  ptr @awaitSuspendFn)

Then it is much easier to perform the safety analysis in the middle
end. If it is safe to inline the call to awaitSuspend, we can replace it
in the CoroEarly pass. Otherwise we could replace it in the CoroSplit
pass.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D157833
2023-08-28 17:07:30 +08:00
dingfei
8d60e10ce4 [AST][Coroutine] Fix CoyieldExpr missing end loc
Coroutine co_yield/co_await/co_return are implemented by a serious of
synthesized CXXMemberExpr which have no lexical right-side parenthesis.

This fix uses the end loc of inner expr as the hypothetical RParenLoc of
CXXMemberExpr. For tools this might be an issue since the RParen token doesn't
exist (but has a valid location).

For future improvement, we might:
1. mark those inner (generated) exprs as implict (tools have chances to skip
   these nodes) (by @aaron.ballman)
2. borrow the idea from InitListExpr, there are two forms, one is for semantic,
   the other one is for syntactic, having these two split can make everything
   easier (by @hokein)

Fixes https://github.com/llvm/llvm-project/issues/64483

Reviewed By: aaron.ballman, hokein

Differential Revision: https://reviews.llvm.org/D157296
2023-08-10 08:02:32 +08:00
Chuanqi Xu
616c806707 [C++20] [Coroutines] Handle function-try-block in SemaCoroutine
In https://reviews.llvm.org/D146758, we handled the rare case that the
coroutine has a function-try-block. But it will be better to handle it
in the Sema part. This patch handles the preprocess.
2023-04-06 15:11:34 +08:00
Bruno Cardoso Lopes
fa0d4e1f12 [Coroutines] Implement fix for cwg2563 issue and enable RVO under certain conditions
- The cwg2563 issue is fixed by delaying GRO initialization only when the types
  mismatch between GRO and function return.
- When the types match directly initialize, which indirectly enables RVO to
  kick in, partially restores behavior introduced in
  https://reviews.llvm.org/D117087.
- Add entry to release notes.

Background:
https://github.com/llvm/llvm-project/issues/56532
https://cplusplus.github.io/CWG/issues/2563.html
https://github.com/cplusplus/papers/issues/1414

Differential Revision: https://reviews.llvm.org/D145641
2023-03-21 21:42:31 -07:00
Bruno Cardoso Lopes
43f5085fa8 [Coroutines] Fix premature conversion of return object
Fix https://github.com/llvm/llvm-project/issues/56532

Effectively, this reverts behavior introduced in https://reviews.llvm.org/D117087,
which did two things:

1. Change delayed to early conversion of return object.
2. Introduced RVO possibilities because of early conversion.

This patches fixes (1) and removes (2). I already worked on a follow up for (2)
in a separated patch. I believe it's important to split these two because if the RVO
causes any problems we can explore reverting (2) while maintaining (1).

Notes on some testcase changes:
- `pr59221.cpp` changed to `-O1` so we can check that the front-end honors
  the value checked for. Sounds like `-O3` without RVO is more likely
  to work with LLVM optimizations...
- Comment out delete members `coroutine-no-move-ctor.cpp` since behavior
  now requires copies again.

Differential Revision: https://reviews.llvm.org/D145639
2023-03-21 21:42:25 -07:00
Ilya Biryukov
4361ba791c Revert "[Coroutines] Fix premature conversion of return object"
This reverts commit 54225c457a336b1609c6d064b2b606a9238a28b9.
The lack of RVO causes compile errors in our code.
Reverting to unblock our integrate.

See D145639 for full discussion.
2023-03-17 17:01:43 +01:00
Bruno Cardoso Lopes
54225c457a [Coroutines] Fix premature conversion of return object
Fix https://github.com/llvm/llvm-project/issues/56532

Effectively, this reverts behavior introduced in https://reviews.llvm.org/D117087,
which did two things:

1. Change delayed to early conversion of return object.
2. Introduced RVO possibilities because of early conversion.

This patches fixes (1) and removes (2). I already worked on a follow up for (2)
in a separated patch. I believe it's important to split these two because if the RVO
causes any problems we can explore reverting (2) while maintaining (1).

Notes on some testcase changes:
- `pr59221.cpp` changed to `-O1` so we can check that the front-end honors
  the value checked for. Sounds like `-O3` without RVO is more likely
  to work with LLVM optimizations...
- Comment out delete members `coroutine-no-move-ctor.cpp` since behavior
  now requires copies again.

Differential Revision: https://reviews.llvm.org/D145639
2023-03-09 14:18:26 -08:00
Chuanqi Xu
55900a0d20 Recommit [Coroutines] Stop supportting std::experimental::coroutine_traits
As we discussed before, we should stop supporting
std::experimental::coroutine_traits in clang17. Now the clang16 is
branched so we can clean them now.

All the removed tests have been duplicated before.
2023-02-20 10:27:02 +08:00
Chuanqi Xu
6d5ea6b123 Revert "[Coroutines] Stop supportting std::experimental::coroutine_traits"
This reverts commit c4e6e771f255fb1da3d505534997b6a88195b012.

Since clang-tools-extra contains the use for
std::experimental::coroutine_traits, the previsou commit breaks the
build bot. Revert this one to make the bot green.
2023-02-17 15:50:54 +08:00
Chuanqi Xu
c4e6e771f2 [Coroutines] Stop supportting std::experimental::coroutine_traits
As we discussed before, we should stop supporting
std::experimental::coroutine_traits in clang17. Now the clang16 is
branched so we can clean them now.

All the removed tests have been duplicated before.
2023-02-17 15:35:17 +08:00
Chuanqi Xu
d2b0b26132 [Coroutines] Pass size parameter for deallocation function when qualified
Close https://github.com/llvm/llvm-project/issues/60545.

Previously, we would only pass the size parameter to the deallocation
function if the type is completely the same. But it is good enough to
make them unqualified the smae.
2023-02-07 00:22:22 +08:00
Chuanqi Xu
cc526e346d [C++20] [Coroutines] Disable to take the address of labels in coroutines
Closing https://github.com/llvm/llvm-project/issues/56436

We can't support the GNU address of label extension in coroutines well
in current architecture. Since the coroutines are going to split into
pieces in the middle end so the address of labels are ambiguous that
time.

To avoid any further misunderstanding, we try to emit an error here.

Differential Revision: https://reviews.llvm.org/D131938
2023-01-17 11:35:32 +08:00
Kazu Hirata
8595f2e54d [Sema] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 11:13:39 -08:00
Chuanqi Xu
b72a364bb5 [C++20] [Coroutines] Exit early if we found co_await appears in
unevaluated context

Closes https://github.com/llvm/llvm-project/issues/58133

The direct cause for this issue is that the compilation process
continues after it found it is in a invalid state. [expr.await]p2 says
clearly that the co_await expressions are not allowed to appear in
unevaluated context. So we can exit early in this case. It also reduces
many redundant diagnostic messages (Such as 'expression with side
effects has no effect in an unevaluated context').
2022-10-09 14:59:27 +08:00
Chuanqi Xu
327141fb1d [C++] [Coroutines] Prefer aligned (de)allocation for coroutines -
implement the option2 of P2014R0

This implements the option2 of
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2014r0.pdf.

This also fixes https://github.com/llvm/llvm-project/issues/56671.

Although wg21 didn't get consensus for the direction of the problem,
we're happy to have some implementation and user experience first. And
from issue56671, the option2 should be the pursued one.

Reviewed By: ychen

Differential Revision: https://reviews.llvm.org/D133341
2022-09-22 11:28:29 +08:00
Chuanqi Xu
1c0a90fd47 [C++20] [Coroutines] Prefer sized deallocation in promise_type
Now when the compiler can't find the sized deallocation function
correctly in promise_type if there are multiple deallocation function
overloads there.

According to [dcl.fct.def.coroutine]p12:
> If both a usual deallocation function with only a pointer parameter
> and a usual deallocation function with both a pointer parameter and a
> size parameter are found, then the selected deallocation function
> shall be the one with two parameters.

So when there are multiple deallocation functions, the compiler should
choose the sized one instead of the unsized one. The patch fixes this.
2022-09-14 15:07:31 +08:00
Chuanqi Xu
5f571eeb3f [NFC] [Frontend] Correct the use of 'auto' in SemaCoroutine and CGCoroutine
We should only use 'auto' in case we can know the type from the right
hand side of the expression. Also we need keep '*' around if the type is
a pointer actually. Few uses of 'auto' in SemaCoroutine.cpp and
CGCoroutine.cpp violates the rule. This commit tries to fix it.
2022-09-07 10:45:01 +08:00
Chuanqi Xu
69e920d426 [Coroutines] Use LookupAllocationFunction to find allocation functions for coroutines consistently
Previously we may call Sema::FindAllocationFunctions directly to lookup
allocation functions directly instead of using our wrapped lambda
LookupAllocationFunction, which is slightly incosnsistent. It will be
helpful to refactor this for further changes.

Also previously, when we lookup 'operator new(std::size_t, std::nothrow_t)' in
case we found `get_­return_­object_­on_­allocation_­failure` in the
promise_type, the compiler will try to look at the allocation function
in promise_type. However, this is not wanted actually. According to
[dcl.fct.def.coroutine]p10:

> if a global allocation function is selected, the
> ::operator new(size_­t, nothrow_­t) form is used.

So we should only lookup for `::operator (size_t, nothrow_t)` for the
global allocation function. For the allocation function in the
promise_type, the requirement is that it shouldn't throw, which has
already been checked.

Given users generally include headers from standard libs so it will
generally include the <new> header, so this change should be a trivial
one and shouldn't affect almost any user.
2022-09-05 15:20:09 +08:00
Chuanqi Xu
085e8cd8d3 [NFC] Cleanup lookup for coroutine allocation/deallocation 2022-09-02 17:24:52 +08:00
Chuanqi Xu
448995c521 [NFC] [Coroutines] Add test for ambiguous allocation functions in
promise_type

Address the post-commit comment in
https://reviews.llvm.org/D125517#inline-1217244
2022-06-06 14:23:35 +08:00
Chuanqi Xu
a1ffba8d52 [C++20] [Coroutines] Conform the updates for CWG issue 2585
According to the updates in CWG issue 2585
https://cplusplus.github.io/CWG/issues/2585.html, we shouldn't find an
allocation function with (size, p0, …, pn) in global scope.

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D126187
2022-05-25 10:31:26 +08:00
Chuanqi Xu
9e9cf3fa3d Revert "[C++20] [Coroutines] Conform the updates for CWG issue 2585"
This reverts commit 1b89a25a9b960886e486eb20b755634613c088f8.

The test would fail in windows versions.
2022-05-23 16:21:42 +08:00
Chuanqi Xu
1b89a25a9b [C++20] [Coroutines] Conform the updates for CWG issue 2585
According to the updates in CWG issue 2585
https://cplusplus.github.io/CWG/issues/2585.html, we shouldn't find an
allocation function with (size, p0, …, pn) in global scope.
2022-05-23 15:49:17 +08:00
Nathan Ridge
df2a4eae6b [clang] Expose CoawaitExpr's operand in the AST
Previously the Expr returned by getOperand() was actually the
subexpression common to the "ready", "suspend", and "resume"
expressions, which often isn't just the operand but e.g.
await_transform() called on the operand.

It's important for the AST to expose the operand as written
in the source for traversals and tools like clangd to work
correctly.

Fixes https://github.com/clangd/clangd/issues/939

Differential Revision: https://reviews.llvm.org/D115187
2022-05-17 08:13:37 -04:00
Chuanqi Xu
452fac9534 [Frontend] [Coroutines] Emit error when we found incompatible allocation
function in promise_type

According to https://cplusplus.github.io/CWG/issues/2585.html, this
fixes https://github.com/llvm/llvm-project/issues/54881

Simply, the clang tried to found (do lookup and overload resolution. Is
there any better word to use than found?) allocation function in
promise_type and global scope. However, this is not consistent with the
standard. The standard behavior would be that the compiler shouldn't
lookup in global scope in case we lookup the allocation function name in
promise_type. In other words, the program is ill-formed if there is
incompatible allocation function in promise type.

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D125517
2022-05-17 10:36:21 +08:00
Jun Zhang
7fde4e2213
Add some helpers to better check Scope's kind. NFC
Signed-off-by: Jun Zhang <jun@junz.org>
2022-04-16 11:31:40 +08:00
Benjamin Kramer
5d2ce7663b Use llvm::append_range instead of push_back loops where applicable. NFCI. 2022-03-18 01:25:34 +01:00
Chuanqi Xu
d30ca5e2e2 [C++20] [Coroutines] Implement return value optimization for get_return_object
This patch tries to implement RVO for coroutine's return object got from
get_return_object.
From [dcl.fct.def.coroutine]/p7 we could know that the return value of
get_return_object is either a reference or a prvalue. So it makes sense
to do copy elision for the return value. The return object should be
constructed directly into the storage where they would otherwise be
copied/moved to.

Test Plan: folly, check-all

Reviewed By: junparser

Differential revision: https://reviews.llvm.org/D117087
2022-02-16 13:38:00 +08:00
Simon Pilgrim
fbe0ca576d [clang][sema] checkNoThrow - use cast<> instead of dyn_cast<> to avoid dereference of nullptr
The pointer is referenced immediately, so assert the cast is correct instead of returning nullptr
2022-02-12 11:18:49 +00:00
Chuanqi Xu
e39ba04617 [C++20] [Coroutines] Warning for always_inline coroutine
See the discussion in https://reviews.llvm.org/D100282. The coroutine
marked always inline might not be inlined properly in current compiler
support. Since the coroutine would be splitted into pieces. And the call
to resume() and destroy() functions might be indirect call. Also the
ramp function wouldn't get inlined under O0 due to pipeline ordering
problems. It might be different to what users expects to. Emit a warning
to tell it.

This is what GCC does too: https://godbolt.org/z/7eajb1Gf8

Reviewed By: Quuxplusone

Differential Revision: https://reviews.llvm.org/D115867
2022-02-08 11:43:42 +08:00
Arthur O'Dwyer
424400da2d [clang][NFC] Change some ->getType()->isPlaceholderType() to just ->hasPlaceholderType()
Differential Revision: https://reviews.llvm.org/D118518
2022-01-29 10:20:22 -05:00
Chuanqi Xu
4f4340ee2a [NFC] [Coroutines] Refactor implementation in checkFinalSuspendNoThrow
Now when we are checking if the expression `co_await
promise.final_suspend()` is not throw, we would check unconditionally
for its child expressions recursively. It takes unnecessary time. And
the compiler would complains if the implementation in final_suspend()
may throw even if the higher level function signature marked noexcept
already.

This fixes bug48453 too.
2022-01-14 15:37:01 +08:00
Chuanqi Xu
bbced74199 [NFC] Remove invisible character in comments 2022-01-12 14:10:18 +08:00
Nathan Sidwell
b50fea47b6 [clang] Allow using std::coroutine_traits in std::experimental
This is that diff I was aiming for.  When transitioning code from
coroutines-ts to c++20, it can be useful to add a using declaration to
std::experimental pointing to std::coroutine_traits.  This permits
that use by checking whether lookup in std::experimentl finds a
different decl to lookup in std.  You still get a warning about
std::experimental::coroutine_traits being a thing, just not an error.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D115943
2022-01-02 15:48:16 -05:00
Nathan Sidwell
d4f09786e0 [clang] More informative mixed namespace diagnostics
First, let's check we get a TemplateDecl, before complaining about
where it might have been found.

Second, if it came from an unexpected place, show where that location is.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D116164
2022-01-02 12:23:13 -05:00
Chuanqi Xu
097208dbf0 [C++20] [Coroutines] Allow promise_type to not define return_void or return_value
According to [dcl.fct.def.coroutine]p6, the promise_type is allowed to
not define return_void nor return_value:

> If searches for the names return_­void and return_­value in the scope
> of the promise type each find any declarations, the program is
> ill-formed.
> [Note 1: If return_­void is found, flowing off the end of a coroutine is
> equivalent to a co_­return with no operand. Otherwise, flowing off the
> end of a coroutine results in
> undefined behavior ([stmt.return.coroutine]). — end note]

So the program isn't ill-formed if the promise_type doesn't define
return_void nor return_value. It is just a potential UB. So the program
should be allowed to compile.

Reviewed By: urnathan

Differential Revision: https://reviews.llvm.org/D116204
2021-12-24 13:37:51 +08:00
Chuanqi Xu
f3d4e168db [C++20] Conform coroutine's comments in clang (NFC-ish)
The comments for coroutine in clang wrote for coroutine-TS. Now
coroutine is merged into standard. Try to conform the comments.
2021-12-24 12:41:44 +08:00
Nathan Sidwell
d4de2a4d59 [clang][NFC] Refactor coroutine_traits lookup
To allow transition from the TS-specified
std::experimental::coroutine_traits to the C++20-specified
std::coroutine_traits, we lookup in both places and provide helpful
diagnostics. This refactors the code to avoid separate paths to
std::experimental lookups.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D116029
2021-12-21 10:29:01 -05:00
Nathan Sidwell
565c17574d [clang] Adjust coroutine namespace diagnostics
The diagnostics concerning mixing std::experimental and std are
somewhat wordy and have some typographical errors.  Diagnostics do not
start with a capital letter nor end with a fullstop.  Usually we try
and link clauses with a semicolon, rather than start a new sentence.
So that's what this patch does.  Along with avoiding repetition about
std::experimental going away.

Differential Revision: https://reviews.llvm.org/D116026
2021-12-20 08:50:16 -08:00
Chuanqi Xu
af9f3c6d86 [Coroutine] Warn deprecated 'std::experimental::coro' uses
Since we've decided the to not support std::experimental::coroutine*, we
should tell the user they need to update.

Reviewed By: Quuxplusone, ldionne, Mordante

Differential Revision: https://reviews.llvm.org/D113977
2021-11-18 09:41:01 +08:00
Chuanqi Xu
ec117158a3 [Coroutines] [Frontend] Lookup in std namespace first
Now in libcxx and clang, all the coroutine components are defined in
std::experimental namespace.
And now the coroutine TS is merged into C++20. So in the working draft
like N4892, we could find the coroutine components is defined in std
namespace instead of std::experimental namespace.
And the coroutine support in clang seems to be relatively stable. So I
think it may be suitable to move the coroutine component into the
experiment namespace now.

This patch would make clang lookup coroutine_traits in std namespace
first. For the compatibility consideration, clang would lookup in
std::experimental namespace if it can't find definitions in std
namespace. So the existing codes wouldn't be break after update
compiler.

And in case the compiler found std::coroutine_traits and
std::experimental::coroutine_traits at the same time, it would emit an
error for it.

The support for looking up std::experimental::coroutine_traits would be
removed in Clang16.

Reviewed By: lxfind, Quuxplusone

Differential Revision: https://reviews.llvm.org/D108696
2021-11-04 11:53:47 +08:00
Matheus Izvekov
d9308aa39b [clang] don't mark as Elidable CXXConstruct expressions used in NRVO
See PR51862.

The consumers of the Elidable flag in CXXConstructExpr assume that
an elidable construction just goes through a single copy/move construction,
so that the source object is immediately passed as an argument and is the same
type as the parameter itself.

With the implementation of P2266 and after some adjustments to the
implementation of P1825, we started (correctly, as per standard)
allowing more cases where the copy initialization goes through
user defined conversions.

With this patch we stop using this flag in NRVO contexts, to preserve code
that relies on that assumption.
This causes no known functional changes, we just stop firing some asserts
in a cople of included test cases.

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D109800
2021-09-21 21:41:20 +02:00