llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Harlen Batagelo (hbatagelo)
<details>
<summary>Changes</summary>
Fixes #<!-- -->201632.
This patch fixes an assertion failure when code completion is triggered inside
an ill-formed lambda's trailing requires-clause, as in
```cpp
void f() {
[]() requires x /*invoke completion here*/
```
https://godbolt.org/z/a66s7Y5cx
When `tok::code_completion` is reached, parsing is cut off before the end of
the declarator. This leaves the lambda's call operator without a type, thus
triggering the `!isNull() && "Cannot retrieve a NULL type pointer"`
assertion when `AddOrdinaryNameResults` calls `FunctionDecl::getReturnType()`
later.
Fix by guarding the `getReturnType()` call with a null check.
Note: The crash stacktrace for the reproducer above differs slightly from #<!--
-->201632. Here, parsing is cut off during the parsing of the constraint
expression. In #<!-- -->201632, parsing is cut off later during actual template
parsing in `Parser::ParseTemplateIdAfterTemplateName`. Both leave the lambda
without a `FunctionType`. Tests for both are included.
---
Full diff: https://github.com/llvm/llvm-project/pull/206373.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/lib/Sema/SemaCodeComplete.cpp (+5-3)
- (added) clang/test/CodeCompletion/GH201632.cpp (+13)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d6b978ec91659..7f65d15161734 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1060,6 +1060,7 @@ Code Completion
- Fixed a crash in code completion when using a C-Style cast with a
parenthesized
operand in Objective-C++ mode. (#GH180125)
+- Fixed a crash when code completion is triggered inside an ill-formed
lambda's trailing requires-clause. (#GH201632)
Static Analyzer
---------------
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp
b/clang/lib/Sema/SemaCodeComplete.cpp
index bef5eea9ed442..ffa593afdea96 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -2625,9 +2625,11 @@
AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
// "return expression ;" or "return ;", depending on the return type.
QualType ReturnType;
- if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
- ReturnType = Function->getReturnType();
- else if (const auto *Method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
+ if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) {
+ if (!Function->getType().isNull())
+ ReturnType = Function->getReturnType();
+ } else if (const auto *Method =
+ dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
ReturnType = Method->getReturnType();
else if (SemaRef.getCurBlock() &&
!SemaRef.getCurBlock()->ReturnType.isNull())
diff --git a/clang/test/CodeCompletion/GH201632.cpp
b/clang/test/CodeCompletion/GH201632.cpp
new file mode 100644
index 0000000000000..53ff57a652957
--- /dev/null
+++ b/clang/test/CodeCompletion/GH201632.cpp
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -std=c++20 -fsyntax-only -code-completion-at=%s:7:39 %s
-DTEST_TEMPLATE
+// RUN: not %clang_cc1 -std=c++20 -fsyntax-only -code-completion-at=%s:12:19
%s -DTEST_CONSTRAINT
+
+#ifdef TEST_TEMPLATE
+void template_cutoff() {
+ [=]() mutable -> decltype(y + x)
+ requires(is_same<decltype((y)), int /*invoke completion here*/ &>
+#endif
+
+#ifdef TEST_CONSTRAINT
+void constraint_cutoff() {
+ []() requires x /*invoke completion here*/
+#endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/206373
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits