[clang] ad2d6bb - Fix potential infinite loop with malformed attribute syntax

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 15 07:47:56 PDT 2021


Author: Aaron Ballman
Date: 2021-04-15T10:47:32-04:00
New Revision: ad2d6bbb1435cef0a048c9aed3dcf9617640f222

URL: https://github.com/llvm/llvm-project/commit/ad2d6bbb1435cef0a048c9aed3dcf9617640f222
DIFF: https://github.com/llvm/llvm-project/commit/ad2d6bbb1435cef0a048c9aed3dcf9617640f222.diff

LOG: Fix potential infinite loop with malformed attribute syntax

Double square bracket attribute arguments can be arbitrarily complex,
and the attribute argument parsing logic recovers by skipping tokens.
As a fallback recovery mechanism, parse recovery stops before reading a
semicolon. This could lead to an infinite loop in the attribute list
parsing logic.

Added: 
    

Modified: 
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/test/Parser/c2x-attributes.c
    clang/test/Parser/cxx-attributes.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index bc59b41782577..af3d0df53e91b 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4214,7 +4214,7 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
   llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs;
 
   bool AttrParsed = false;
-  while (Tok.isNot(tok::r_square)) {
+  while (!Tok.isOneOf(tok::r_square, tok::semi)) {
     if (AttrParsed) {
       // If we parsed an attribute, a comma is required before parsing any
       // additional attributes.
@@ -4279,6 +4279,13 @@ void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
         << AttrName;
   }
 
+  // If we hit an error and recovered by parsing up to a semicolon, eat the
+  // semicolon and don't issue further diagnostics about missing brackets.
+  if (Tok.is(tok::semi)) {
+    ConsumeToken();
+    return;
+  }
+
   SourceLocation CloseLoc = Tok.getLocation();
   if (ExpectAndConsume(tok::r_square))
     SkipUntil(tok::r_square);

diff  --git a/clang/test/Parser/c2x-attributes.c b/clang/test/Parser/c2x-attributes.c
index 48bb19707dd10..d75e9e2d29768 100644
--- a/clang/test/Parser/c2x-attributes.c
+++ b/clang/test/Parser/c2x-attributes.c
@@ -16,6 +16,7 @@ enum { [[]] Six }; // expected-error {{expected identifier}}
 // FIXME: this diagnostic can be improved.
 enum E3 [[]] { Seven }; // expected-error {{expected identifier or '('}}
 
+[[deprecated([""])]] int WrongArgs; // expected-error {{expected expression}}
 [[,,,,,]] int Commas1; // ok
 [[,, maybe_unused]] int Commas2; // ok
 [[maybe_unused,,,]] int Commas3; // ok

diff  --git a/clang/test/Parser/cxx-attributes.cpp b/clang/test/Parser/cxx-attributes.cpp
index 2b874e4aca7fd..d445e42bfe08e 100644
--- a/clang/test/Parser/cxx-attributes.cpp
+++ b/clang/test/Parser/cxx-attributes.cpp
@@ -35,6 +35,7 @@ void fn() {
   pi = &i[0];
 }
 
+[[deprecated([""])]] int WrongArgs; // expected-error {{expected variable name or 'this' in lambda capture list}}
 [[,,,,,]] int Commas1; // ok
 [[,, maybe_unused]] int Commas2; // ok
 [[maybe_unused,,,]] int Commas3; // ok


        


More information about the cfe-commits mailing list