From e417f02b5159c13f011335636faaf8c6847b627f Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 15 Mar 2023 01:07:55 +0800 Subject: [PATCH] [SemaCXX]use CorrectDelayedTyposInExpr in ActOnCXXFoldExpr only when Diag 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 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaTemplateVariadic.cpp | 5 +++-- clang/test/SemaCXX/fold_expr_typo.cpp | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/fold_expr_typo.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a52af53..5fae7ce 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -197,6 +197,8 @@ Bug Fixes in This Version be reached despite being reachable. This fixes `#61177 `_ in anticipation of `CWG2699 _` being accepted by WG21. +- Fix crash when parsing fold expression containing a delayed typo correction. + (`#61326 `_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 86268b5..dfcc78d 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1220,10 +1220,11 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, 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); diff --git a/clang/test/SemaCXX/fold_expr_typo.cpp b/clang/test/SemaCXX/fold_expr_typo.cpp new file mode 100644 index 0000000..0ef9c15 --- /dev/null +++ b/clang/test/SemaCXX/fold_expr_typo.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s + +template +void foo(T &&...Params) { + foo(Unknown); // expected-error {{expression contains unexpanded parameter pack 'T'}}\ + expected-error {{use of undeclared identifier 'Unknown'}} + ((foo(Unknown)), ...); // expected-error {{use of undeclared identifier 'Unknown'}} +} + +template struct A { + template void foo(T &&...Params) { + foo((... + static_cast(1))); // expected-error {{expression contains unexpanded parameter pack 'T'}} + } +}; -- 2.7.4