PR #61326
- fix clang crash when fold expression contains a delayed typos correction.
code snippet in `ActOnCXXFoldExpr`
``` if (!LHS || !RHS) {
Expr *Pack = LHS ? LHS : RHS;
assert(Pack && "fold expression with neither LHS nor RHS");
DiscardOperands();
if (!Pack->containsUnexpandedParameterPack())
return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
<< Pack->getSourceRange();
}
```
`DiscardOperands` will be triggered when LHS/RHS is delayed typo correction expression.
It will output and clean all diagnose but still return a valid expression. (in else branch)
valid expression will be handled in caller function. When caller wants to output the diagnose, the diagnose in delayed typo correction expression has been consumed in `ActOnCXXFoldExpr`. It causes clang crash.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D145892
be reached despite being reachable. This fixes
`#61177 <https://github.com/llvm/llvm-project/issues/61177>`_ in anticipation
of `CWG2699 <https://wg21.link/CWG2699>_` being accepted by WG21.
+- Fix crash when parsing fold expression containing a delayed typo correction.
+ (`#61326 <https://github.com/llvm/llvm-project/issues/61326>`_)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if (!LHS || !RHS) {
Expr *Pack = LHS ? LHS : RHS;
assert(Pack && "fold expression with neither LHS nor RHS");
- DiscardOperands();
- if (!Pack->containsUnexpandedParameterPack())
+ if (!Pack->containsUnexpandedParameterPack()) {
+ DiscardOperands();
return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
<< Pack->getSourceRange();
+ }
}
BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+template <typename... T>
+void foo(T &&...Params) {
+ foo<T>(Unknown); // expected-error {{expression contains unexpanded parameter pack 'T'}}\
+ expected-error {{use of undeclared identifier 'Unknown'}}
+ ((foo<T>(Unknown)), ...); // expected-error {{use of undeclared identifier 'Unknown'}}
+}
+
+template <typename... U> struct A {
+ template <typename... T> void foo(T &&...Params) {
+ foo<T>((... + static_cast<U>(1))); // expected-error {{expression contains unexpanded parameter pack 'T'}}
+ }
+};