Author: Vlad Serebrennikov Date: 2024-08-01T17:56:15+04:00 New Revision: 130c135689ec12ab78c53645808524a8d28f7cae
URL: https://github.com/llvm/llvm-project/commit/130c135689ec12ab78c53645808524a8d28f7cae DIFF: https://github.com/llvm/llvm-project/commit/130c135689ec12ab78c53645808524a8d28f7cae.diff LOG: [clang] Fix crash with multiple non-parenthsized `sizeof` (#101297) There are 5 unary operators that can be followed by a non-parenthesized expression: `sizeof`, `__datasizeof`, `__alignof`, `alignof`, `_Alignof`. When we nest them too deep, `BalancedDelimiterTracker` does not help, because there are no parentheses, and we crash. Instead, this patch recognize chains of those operators, and parse them with sufficient stack space. Fixes #45061 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Parse/ParseExpr.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3c2e0282d1c72..ba70b138a04c4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -183,6 +183,9 @@ Miscellaneous Clang Crashes Fixed - Fixed a crash in C due to incorrect lookup that members in nested anonymous struct/union can be found as ordinary identifiers in struct/union definition. (#GH31295) +- Fixed a crash caused by long chains of ``sizeof`` and other similar operators + that can be followed by a non-parenthesized expression. (#GH45061) + OpenACC Specific Changes ------------------------ diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index e82b565272831..e501d5e91e77d 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2479,7 +2479,19 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, return ExprError(); } - Operand = ParseCastExpression(UnaryExprOnly); + // If we're parsing a chain that consists of keywords that could be + // followed by a non-parenthesized expression, BalancedDelimiterTracker + // is not going to help when the nesting is too deep. In this corner case + // we continue to parse with sufficient stack space to avoid crashing. + if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, + tok::kw_alignof, tok::kw__Alignof) && + Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof, + tok::kw_alignof, tok::kw__Alignof)) + Actions.runWithSufficientStackSpace(Tok.getLocation(), [&] { + Operand = ParseCastExpression(UnaryExprOnly); + }); + else + Operand = ParseCastExpression(UnaryExprOnly); } else { // If it starts with a '(', we know that it is either a parenthesized // type-name, or it is a unary-expression that starts with a compound _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits