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 <template <class> concept... CC>`) result in an assertion failure in `CheckVarOrConceptTemplateTemplateId`: `Assertion 'Parameter && "A variable template id without template?"' failed.` **Solution** Added a check for `!Parameter || Parameter->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
