[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-07 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

> @falbrechtskirchinger Ooops, yes, it's true that the bug is gone w/ #79.
> 
> But I'd say if we're going to cherry-pick #79, we have to backport its 
> precedent #103867 as well, so I think we can probably go ahead with this one 
> and backport it to 19, and then we can revert this one on the trunk - this is 
> indeed a bit awkward, but it depends whether it's worth backporting #103867 
> @cor3ntin

I'd like this crash to be fixed in 19.x.


> (Again, I apologize for not looking into it so carefully)

No worries.

To summarize: Land this PR and backport it. Revert on trunk. Submit new PR for 
the regression test? (We want to keep that, right?)

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-07 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

@zyn0217 #79 has fixed this crash as well. Should I strip this PR down to 
the unit test, or does it still make sense to you, to keep the changes?

> Will this be backported to 19.x afterwards?

I was also going to ask, though, it's now a question about #79.

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-07 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

> So yes, this one is still necessary - it should occur with an 
> assertion-enabled build when compiling a header containing an invalid concept 
> decl.

Not in my testing.



https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-07 Thread Florian Albrechtskirchinger via cfe-commits


@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr);
   if (TC) {

falbrechtskirchinger wrote:

Because `D->hasTypeConstraint()` does not imply that `D->getTypeConstraint()` 
is non-null, as the code assumed (hence, the assertion).

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-07 Thread Florian Albrechtskirchinger via cfe-commits


@@ -2674,7 +2674,7 @@ void 
ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (D->hasTypeConstraint()) {
+  if (Record.readBool() && D->hasTypeConstraint()) {

falbrechtskirchinger wrote:

Sure. Just waiting on a final verdict, on whether this is still needed.

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-01 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger updated 
https://github.com/llvm/llvm-project/pull/110496

>From 220d76a2b2327318a6b5261896736ddd3f05988a Mon Sep 17 00:00:00 2001
From: Florian Albrechtskirchinger 
Date: Mon, 30 Sep 2024 12:58:15 +0200
Subject: [PATCH] [Serialization] Handle uninitialized type constraints

The ASTWriter currently assumes template type constraints to be
initialized ((bool)getTypeConstraint() == hasTypeConstraint()).
The attached test case presents a scenario where that is not the case.

This patch removes the assumption and adds another boolean to the
serialization, to explicitly encode whether the type constraint has been
initialized.

Fixes #99036
Fixes #109354
---
 clang/lib/Serialization/ASTReaderDecl.cpp  |  2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp  |  5 +++--
 clang/test/PCH/cxx2a-constraints-crash.cpp | 18 ++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7cead2728ca938..90783963934bb0 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2674,7 +2674,7 @@ void 
ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (D->hasTypeConstraint()) {
+  if (Record.readBool() && D->hasTypeConstraint()) {
 ConceptReference *CR = nullptr;
 if (Record.readBool())
   CR = Record.readConceptReference();
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index b71684569609ac..4da2108f553127 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr);
   if (TC) {
 auto *CR = TC->getConceptReference();
 Record.push_back(CR != nullptr);
@@ -1917,7 +1917,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   if (OwnsDefaultArg)
 Record.AddTemplateArgumentLoc(D->getDefaultArgument());
 
-  if (!TC && !OwnsDefaultArg &&
+  if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
   D->getDeclContext() == D->getLexicalDeclContext() &&
   !D->isInvalidDecl() && !D->hasAttrs() &&
   !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
@@ -2580,6 +2580,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // TemplateTypeParmDecl
   Abv->Add(
   BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
+  Abv->Add(BitCodeAbbrevOp(0));// TypeConstraintInitialized
   Abv->Add(BitCodeAbbrevOp(0));// OwnsDefaultArg
   DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
diff --git a/clang/test/PCH/cxx2a-constraints-crash.cpp 
b/clang/test/PCH/cxx2a-constraints-crash.cpp
index 637c55f0c879c9..0527c572e790b3 100644
--- a/clang/test/PCH/cxx2a-constraints-crash.cpp
+++ b/clang/test/PCH/cxx2a-constraints-crash.cpp
@@ -1,7 +1,5 @@
-// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
-// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s
-
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -emit-pch %s -o 
%t -verify
+// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -include-pch %t 
%s -verify
 
 #ifndef HEADER
 #define HEADER
@@ -27,3 +25,15 @@ int main() {
 }
 
 #endif
+
+namespace GH99036 {
+
+template 
+concept C;
+// expected-error@-1 {{expected '='}} \
+// expected-note@-1 {{declared here}}
+
+template  void f();
+// expected-error@-1 {{a concept definition cannot refer to itself}}
+
+} // namespace GH99036

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-21 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

> Bump, it would be nice to have this or that fix backported to 19.x

@vient Backport is happening. #113182

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Concepts] Add regression test for #99036 (PR #113137)

2024-10-21 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger created 
https://github.com/llvm/llvm-project/pull/113137

Add a test case for the assertion error encountered in #99036 and #109354. The 
issue was incidentally fixed by #79.

>From a19b65b8512b103afae697cadf1ccd7cce4ef940 Mon Sep 17 00:00:00 2001
From: Florian Albrechtskirchinger 
Date: Mon, 21 Oct 2024 11:18:29 +0200
Subject: [PATCH] [Concepts] Add regression test for #99036

Add a test case for the assertion error encountered in #99036 and
#109354. The issue was incidentally fixed by #79.
---
 clang/test/PCH/cxx2a-constraints-crash.cpp | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/clang/test/PCH/cxx2a-constraints-crash.cpp 
b/clang/test/PCH/cxx2a-constraints-crash.cpp
index 637c55f0c879c9..5c54ba4c425465 100644
--- a/clang/test/PCH/cxx2a-constraints-crash.cpp
+++ b/clang/test/PCH/cxx2a-constraints-crash.cpp
@@ -1,7 +1,5 @@
-// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
-// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s
-
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -emit-pch -o %t 
%s -verify
+// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -include-pch %t 
%s -verify
 
 #ifndef HEADER
 #define HEADER
@@ -27,3 +25,12 @@ int main() {
 }
 
 #endif
+
+namespace GH99036 {
+
+template 
+concept C; // expected-error {{expected '='}}
+
+template  void f();
+
+} // namespace GH99036

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Concepts] Add regression test for #99036 (PR #113137)

2024-10-21 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

@cor3ntin @zyn0217, please review. This is just the test case from #110496. 
Thanks!

https://github.com/llvm/llvm-project/pull/113137
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-21 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

> I think the best past forward would be to close this PR, and to open a new 
> one targeting the 10.x branch, which a clear explanation that it's not needed 
> in trunk. would that work for you @falbrechtskirchinger ?

Will do.

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Serialization] Handle uninitialized type constraints (PR #110496)

2024-10-21 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger closed 
https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger updated 
https://github.com/llvm/llvm-project/pull/110496

>From 8913503b3fd5518201663395d91b7444232e9856 Mon Sep 17 00:00:00 2001
From: Florian Albrechtskirchinger 
Date: Mon, 30 Sep 2024 12:58:15 +0200
Subject: [PATCH] [clangd][AST] Handle uninitialized type constraints

The ASTWriter currently assumes template type constraints to be
initialized ((bool)getTypeConstraint() == hasTypeConstraint()).
The attached test case presents a scenario where that is not the case.

This patch removes the assumption and adds another boolean to the
serialization, to explicitly encode whether the type constraint has been
initialized.

Fixes #99036.
Fixes #109354.
---
 .../clangd/unittests/ASTTests.cpp | 20 +++
 clang/lib/Serialization/ASTReaderDecl.cpp |  2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp |  5 +++--
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clangd/unittests/ASTTests.cpp 
b/clang-tools-extra/clangd/unittests/ASTTests.cpp
index 32c8e8a63a215a..6bf0667b68f967 100644
--- a/clang-tools-extra/clangd/unittests/ASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ASTTests.cpp
@@ -658,6 +658,26 @@ TEST(ClangdAST, PreferredIncludeDirective) {
 Symbol::IncludeDirective::Import);
 }
 
+TEST(ClangdAST, HandleUninitializedTypeConstraints) {
+  auto TU = TestTU::withHeaderCode(R"cpp(
+template
+concept C; // error-ok
+template
+void f();
+)cpp");
+  TU.ExtraArgs.push_back("-std=c++20");
+
+  auto AST = TU.build();
+
+  const auto &F = llvm::cast(findDecl(AST, "f"));
+  const auto *Params = F.getTemplateParameters();
+  const auto *U = llvm::cast(Params->getParam(0));
+  const auto *TC = U->getTypeConstraint();
+
+  EXPECT_TRUE(U->hasTypeConstraint());
+  EXPECT_FALSE(/*TypeConstraintInitialized=*/TC != nullptr);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7cead2728ca938..90783963934bb0 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2674,7 +2674,7 @@ void 
ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (D->hasTypeConstraint()) {
+  if (Record.readBool() && D->hasTypeConstraint()) {
 ConceptReference *CR = nullptr;
 if (Record.readBool())
   CR = Record.readConceptReference();
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index b71684569609ac..4da2108f553127 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr);
   if (TC) {
 auto *CR = TC->getConceptReference();
 Record.push_back(CR != nullptr);
@@ -1917,7 +1917,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   if (OwnsDefaultArg)
 Record.AddTemplateArgumentLoc(D->getDefaultArgument());
 
-  if (!TC && !OwnsDefaultArg &&
+  if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
   D->getDeclContext() == D->getLexicalDeclContext() &&
   !D->isInvalidDecl() && !D->hasAttrs() &&
   !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
@@ -2580,6 +2580,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // TemplateTypeParmDecl
   Abv->Add(
   BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
+  Abv->Add(BitCodeAbbrevOp(0));// TypeConstraintInitialized
   Abv->Add(BitCodeAbbrevOp(0));// OwnsDefaultArg
   DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

> Thanks again for analyzing & working on this issue.

You’re very welcome! Let's hope I'm on the right track.

> Some suggestions regarding the test:
> 
> 1. As this is more of a clang issue (the offending code belongs to the 
> serialization part of clang), so it is more appropriate to write a clang test 
> instead of a clangd test.
> 
> 2. We don't usually write lit tests but rather unit tests (specifically, 
> tests under the `clangd/unittests` directory) for clangd.

The most recent push contains a clangd unit test. I'd argue that replicating 
the test logic present in clangd (`TestTU`, `ParsedAST`) in clang unit tests is 
unnecessary. Also, the error is specific to clangd. No one has proposed a 
method of triggering the assertion using clang directly.

I've verified that the test triggers the assertion without the changes 
introduced in this PR.
```txt
[ RUN  ] ClangdAST.HandleUninitializedTypeConstraints
ClangdTests: 
/data6/git/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp:1902: void 
clang::ASTDeclWriter::VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl*): 
Assertion `(bool)TC == D->hasTypeConstraint()' failed.
```

If you insist on a clang unit test, I'll need help. :)






https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger edited 
https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger created 
https://github.com/llvm/llvm-project/pull/110496

Note: This patch is based on the assumption, that an assertion causing a crash 
in clangd, is incorrect. Alternatively, the true error may lie elsewhere, 
possibly in ´Sema::BuildTypeConstraint`/`Sema::AttachTypeConstraint`. Someone 
with more experience is needed to make that call.
Commit message follows.



The ASTWriter currently assumes template type constraints to be initialized 
((bool)getTypeConstraint() == hasTypeConstraint()). The attached test case 
presents a scenario where that is not the case.

This patch removes the assumption and adds another boolean to the 
serialization, to explicitly encode whether the type constraint has been 
initialized.

Fixes #99036.
Fixes #109354.

>From 296cc1b1389cc1a7aff4f5a84a48b6db4fe9e59a Mon Sep 17 00:00:00 2001
From: Florian Albrechtskirchinger 
Date: Mon, 30 Sep 2024 12:58:15 +0200
Subject: [PATCH] [clangd] [AST] Handle uninitialized type constraints

The ASTWriter currently assumes template type constraints to be
initialized ((bool)getTypeConstraint() == hasTypeConstraint()).
The attached test case presents a scenario where that is not the case.

This patch removes the assumption and adds another boolean to the
serialization, to explicitly encode whether the type constraint has been
initialized.

Fixes #99036.
Fixes #109354.
---
 clang-tools-extra/clangd/test/GH99036.test | 29 ++
 clang/lib/Serialization/ASTReaderDecl.cpp  |  2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp  |  5 ++--
 3 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clangd/test/GH99036.test

diff --git a/clang-tools-extra/clangd/test/GH99036.test 
b/clang-tools-extra/clangd/test/GH99036.test
new file mode 100644
index 00..64ebe4c75a999d
--- /dev/null
+++ b/clang-tools-extra/clangd/test/GH99036.test
@@ -0,0 +1,29 @@
+# RUN: rm -rf %t
+# RUN: mkdir -p %t
+# RUN: split-file %s %t
+#
+# RUN: not clangd --check=%t/main.cpp 2>&1 | FileCheck -strict-whitespace %s
+#
+# CHECK:  Loaded compilation database
+# CHECK-NEXT: Compile command inferred from main.cpp is:
+# CHECK:  Indexing headers...
+# CHECK-NEXT: [unknown_typename] Line 1: in included file: unknown type name 
'_Up'
+# CHECK:  All checks completed, 1 errors
+
+#--- header.h
+template<_Up>
+concept __decayed_same_as;
+template<__decayed_same_as>
+partial_ordering operator0
+
+#--- main.cpp
+#include "header.h"
+
+#--- compile_commands.json
+[
+  {
+"directory": "/",
+"command": "c++ -std=c++20",
+"file": "main.cpp"
+  }
+]
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7cead2728ca938..90783963934bb0 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2674,7 +2674,7 @@ void 
ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (D->hasTypeConstraint()) {
+  if (Record.readBool() && D->hasTypeConstraint()) {
 ConceptReference *CR = nullptr;
 if (Record.readBool())
   CR = Record.readConceptReference();
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index b71684569609ac..1c9898c042cd4b 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(TC != nullptr); // reflects TypeConstraintInitialized
   if (TC) {
 auto *CR = TC->getConceptReference();
 Record.push_back(CR != nullptr);
@@ -1917,7 +1917,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   if (OwnsDefaultArg)
 Record.AddTemplateArgumentLoc(D->getDefaultArgument());
 
-  if (!TC && !OwnsDefaultArg &&
+  if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
   D->getDeclContext() == D->getLexicalDeclContext() &&
   !D->isInvalidDecl() && !D->hasAttrs() &&
   !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
@@ -2580,6 +2580,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // TemplateTypeParmDecl
   Abv->Add(
   BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
+  Abv->Add(BitCodeAbbrevOp(0));// TypeConstraintInitialized
   Abv->Add(BitCodeAbbrevOp(0));// OwnsDefaultArg
   DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits


@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(TC != nullptr); // reflects TypeConstraintInitialized

falbrechtskirchinger wrote:

Done.

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger updated 
https://github.com/llvm/llvm-project/pull/110496

>From 20042cc1b4ada2065813e118c24236a61e83d1a9 Mon Sep 17 00:00:00 2001
From: Florian Albrechtskirchinger 
Date: Mon, 30 Sep 2024 12:58:15 +0200
Subject: [PATCH] [clangd] [AST] Handle uninitialized type constraints

The ASTWriter currently assumes template type constraints to be
initialized ((bool)getTypeConstraint() == hasTypeConstraint()).
The attached test case presents a scenario where that is not the case.

This patch removes the assumption and adds another boolean to the
serialization, to explicitly encode whether the type constraint has been
initialized.

Fixes #99036.
Fixes #109354.
---
 clang-tools-extra/clangd/test/GH99036.test | 30 ++
 clang/lib/Serialization/ASTReaderDecl.cpp  |  2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp  |  5 ++--
 3 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/clangd/test/GH99036.test

diff --git a/clang-tools-extra/clangd/test/GH99036.test 
b/clang-tools-extra/clangd/test/GH99036.test
new file mode 100644
index 00..6561d9d40ba5b5
--- /dev/null
+++ b/clang-tools-extra/clangd/test/GH99036.test
@@ -0,0 +1,30 @@
+# RUN: rm -rf %t
+# RUN: mkdir -p %t
+# RUN: split-file %s %t
+# RUN: sed -i 's|CWD|%/t|' %t/compile_commands.json
+#
+# RUN: not clangd --check=%t/main.cpp 2>&1 | FileCheck -strict-whitespace %s
+#
+# CHECK:  Loaded compilation database
+# CHECK-NEXT: Compile command from CDB is:
+# CHECK:  Indexing headers...
+# CHECK-NEXT: [expected] Line 1: in included file: expected '='
+# CHECK:  All checks completed, 1 errors
+
+#--- header.h
+template
+concept C;
+template
+void f();
+
+#--- main.cpp
+#include "header.h"
+
+#--- compile_commands.json
+[
+  {
+"directory": "CWD",
+"command": "c++ -std=c++20",
+"file": "main.cpp"
+  }
+]
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7cead2728ca938..90783963934bb0 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2674,7 +2674,7 @@ void 
ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (D->hasTypeConstraint()) {
+  if (Record.readBool() && D->hasTypeConstraint()) {
 ConceptReference *CR = nullptr;
 if (Record.readBool())
   CR = Record.readConceptReference();
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index b71684569609ac..1c9898c042cd4b 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(TC != nullptr); // reflects TypeConstraintInitialized
   if (TC) {
 auto *CR = TC->getConceptReference();
 Record.push_back(CR != nullptr);
@@ -1917,7 +1917,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   if (OwnsDefaultArg)
 Record.AddTemplateArgumentLoc(D->getDefaultArgument());
 
-  if (!TC && !OwnsDefaultArg &&
+  if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
   D->getDeclContext() == D->getLexicalDeclContext() &&
   !D->isInvalidDecl() && !D->hasAttrs() &&
   !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
@@ -2580,6 +2580,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // TemplateTypeParmDecl
   Abv->Add(
   BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
+  Abv->Add(BitCodeAbbrevOp(0));// TypeConstraintInitialized
   Abv->Add(BitCodeAbbrevOp(0));// OwnsDefaultArg
   DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

https://github.com/falbrechtskirchinger updated 
https://github.com/llvm/llvm-project/pull/110496

>From c090601a032c6ba406928821ec4296d190edade5 Mon Sep 17 00:00:00 2001
From: Florian Albrechtskirchinger 
Date: Mon, 30 Sep 2024 12:58:15 +0200
Subject: [PATCH] [clangd][AST] Handle uninitialized type constraints

The ASTWriter currently assumes template type constraints to be
initialized ((bool)getTypeConstraint() == hasTypeConstraint()).
The attached test case presents a scenario where that is not the case.

This patch removes the assumption and adds another boolean to the
serialization, to explicitly encode whether the type constraint has been
initialized.

Fixes #99036.
Fixes #109354.
---
 clang/lib/Serialization/ASTReaderDecl.cpp  |  2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp  |  5 +++--
 clang/test/PCH/cxx2a-constraints-crash.cpp | 15 +++
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7cead2728ca938..90783963934bb0 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2674,7 +2674,7 @@ void 
ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
 
   D->setDeclaredWithTypename(Record.readInt());
 
-  if (D->hasTypeConstraint()) {
+  if (Record.readBool() && D->hasTypeConstraint()) {
 ConceptReference *CR = nullptr;
 if (Record.readBool())
   CR = Record.readConceptReference();
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index b71684569609ac..4da2108f553127 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1899,7 +1899,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr);
   if (TC) {
 auto *CR = TC->getConceptReference();
 Record.push_back(CR != nullptr);
@@ -1917,7 +1917,7 @@ void 
ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   if (OwnsDefaultArg)
 Record.AddTemplateArgumentLoc(D->getDefaultArgument());
 
-  if (!TC && !OwnsDefaultArg &&
+  if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
   D->getDeclContext() == D->getLexicalDeclContext() &&
   !D->isInvalidDecl() && !D->hasAttrs() &&
   !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
@@ -2580,6 +2580,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // TemplateTypeParmDecl
   Abv->Add(
   BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
+  Abv->Add(BitCodeAbbrevOp(0));// TypeConstraintInitialized
   Abv->Add(BitCodeAbbrevOp(0));// OwnsDefaultArg
   DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
diff --git a/clang/test/PCH/cxx2a-constraints-crash.cpp 
b/clang/test/PCH/cxx2a-constraints-crash.cpp
index 637c55f0c879c9..4a74740b918437 100644
--- a/clang/test/PCH/cxx2a-constraints-crash.cpp
+++ b/clang/test/PCH/cxx2a-constraints-crash.cpp
@@ -1,7 +1,5 @@
-// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
-// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s
-
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -emit-pch %s -o 
%t -verify
+// RUN: %clang_cc1 -std=c++2a -fallow-pch-with-compiler-errors -include-pch %t 
%s -verify
 
 #ifndef HEADER
 #define HEADER
@@ -27,3 +25,12 @@ int main() {
 }
 
 #endif
+
+namespace GH99036 {
+
+template 
+concept C; // expected-error {{expected '='}}
+// expected-note@32 {{declared here}}
+template  void f(); // expected-error {{a concept definition cannot refer 
to itself}}
+
+} // namespace GH99036

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits

falbrechtskirchinger wrote:

> We need to resort to `-fallow-pch-with-compiler-errors` :)

Ah, thanks! I would not have figured that out on my own. :)

> Specifically, add the following file to `clang/test/PCH` (or somehow merge it 
> into a pre-existing test, which I'd prefer)

I looked through that directory and found only one test with 
`-fallow-pch-with-compiler-errors` and `-std=c++20`: `race-condition.cpp` – not 
a great fit.

`cxx2a-constraints-crash.cpp` sounds promising and doesn't need too much 
modification. I'm including this in my next push, but I have an annotated 
standalone file based on your suggestion ready to go if needed.


https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clangd] [AST] Handle uninitialized type constraints (PR #110496)

2024-09-30 Thread Florian Albrechtskirchinger via cfe-commits


@@ -27,3 +25,12 @@ int main() {
 }
 
 #endif
+
+namespace GH99036 {
+
+template 
+concept C; // expected-error {{expected '='}}
+// expected-note@32 {{declared here}}

falbrechtskirchinger wrote:

Should have used `@-1` here.

https://github.com/llvm/llvm-project/pull/110496
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits