llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Sriraj2911

<details>
<summary>Changes</summary>

### Fixes #<!-- -->225792

**Problem**
Malformed concept template parameters (e.g., `template &lt;template 
&lt;class&gt; concept... CC&gt;`) result in an assertion failure in 
`CheckVarOrConceptTemplateTemplateId`:
`Assertion 'Parameter &amp;&amp; "A variable template id without template?"' 
failed.`

**Solution**
Added a check for `!Parameter || Parameter-&gt;isInvalidDecl()` in 
`SemaTemplate.cpp` to gracefully exit with `ExprError()` when processing 
invalid declarations instead of crashing.

**Testing**
Added regression test `clang/test/SemaCXX/225792.cpp` and verified via 
`llvm-lit`.

**Use of LLM**
- To understand the exact problem of the issue #<!-- -->225792 
- To filter down the possible causes of this particular crash

---
Full diff: https://github.com/llvm/llvm-project/pull/235408.diff


4 Files Affected:

- (modified) clang/lib/AST/ExprConstant.cpp (+29) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+3) 
- (added) clang/test/SemaCXX/225046.cpp (+10) 
- (added) clang/test/SemaCXX/225792.cpp (+10) 


``````````diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6d390032e2c717..17d3855f0d907a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1538,7 +1538,36 @@ namespace {
         Designator.setInvalid();
         return;
       }
+
+      if(Base){
+        // Mark invalid and return early if Base points to an invalid decl
+        if(const auto *VD = Base.dyn_cast<const ValueDecl *>()){
+          if(VD->isInvalidDecl()){
+            Designator.setInvalid();
+            return;
+          }
+        }
+        // Mark invalid and return early if Base points to an invalid type
+        QualType BaseTy = getType(Base).getNonReferenceType();
+        if(BaseTy.isNull() || BaseTy->containsErrors() || 
(!BaseTy->isPointerType() && !BaseTy->isArrayType())){
+          Designator.setInvalid();
+          return;
+        }
+      }
+
       if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
+        /*
+        When a user writes invalid C++ code (e.g., declaring a 
+        variable as void and then illegally re-declaring/indexing 
+        it as an array), the AST node representing Base ends up
+        with an invalid or unexpected type structure. 
+        => getType(Base) does not fulfill either conditions, causing
+        the assert statement to fail and crash the compiler.
+        */
+       /*
+       To get a clean error, add a check before entering the above
+       if clause
+       */
         assert(!Base || getType(Base).getNonReferenceType()->isPointerType() ||
                getType(Base).getNonReferenceType()->isArrayType());
         Designator.FirstEntryIsAnUnsizedArray = true;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5a61cb852d15e5..0b4d7343b901f5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4874,6 +4874,9 @@ ExprResult Sema::CheckVarOrConceptTemplateTemplateId(
     const TemplateArgumentListInfo *TemplateArgs) {
   TemplateTemplateParmDecl *Parameter =
       Template.getAsTemplateTemplateParmDecl();
+  if(!Parameter || Parameter->isInvalidDecl()){
+    return ExprError();
+  }
   assert(Parameter && "A variable template id without template?");
 
   if (Parameter->templateParameterKind() !=
diff --git a/clang/test/SemaCXX/225046.cpp b/clang/test/SemaCXX/225046.cpp
new file mode 100644
index 00000000000000..98c22f8b1a5691
--- /dev/null
+++ b/clang/test/SemaCXX/225046.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void a; // expected-error {{variable has incomplete type 'void'}}
+extern int a[];
+
+void test() {
+  // Force constant evaluation of &a[6].
+  // Before the fix this asserted in LValue::addUnsizedArray.
+  (void)__builtin_constant_p(&a[6]);
+}
\ No newline at end of file
diff --git a/clang/test/SemaCXX/225792.cpp b/clang/test/SemaCXX/225792.cpp
new file mode 100644
index 00000000000000..eec8be8c100d9f
--- /dev/null
+++ b/clang/test/SemaCXX/225792.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+template <class T>
+concept C = true;
+
+template <template <class> concept... CC> // expected-error {{concept template 
parameter is a C++2c extension}}
+int foo(CC &) { return 42; } // expected-error {{expected 'auto' or 
'decltype(auto)' after concept name}} \
+                             // expected-note {{candidate template ignored: 
constraints not satisfied}}
+
+static_assert(foo<C>(0) == 42, ""); // expected-error {{no matching function 
for call to 'foo'}}
\ No newline at end of file

``````````

</details>


https://github.com/llvm/llvm-project/pull/235408
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to