[clang] 130c135 - [clang] Fix crash with multiple non-parenthsized `sizeof` (#101297)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 1 06:56:18 PDT 2024


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


        


More information about the cfe-commits mailing list