[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-09-02 Thread Hu Jialun via Phabricator via cfe-commits
SuibianP created this revision.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
SuibianP requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The parser assumes that the lexer never emits coloncolon token for
C code, but this assumption no longer holds in C2x attribute namespaces.
As a result, stray coloncolon tokens out of attributes cause assertion
failures and hangs in release build, which this patch tries to handle.

Crash input minimal example: T n::v


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133248

Files:
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/Parser.cpp
  clang/test/Parser/c2x-attributes.c


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot 
appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as 
scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2060,9 +2060,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope 
either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5336,6 +5336,8 @@
 return isDeclarationSpecifier();
 
   case tok::coloncolon:   // ::foo::bar
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::new
 NextToken().is(tok::kw_delete))   // ::delete
   return false;
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -860,10 +860,11 @@
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
   bool MightBeCXXScopeToken() {
-return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
-   (Tok.is(tok::annot_template_id) &&
-NextToken().is(tok::coloncolon)) ||
-   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+return (getLangOpts().CPlusPlus) &&
+   (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+(Tok.is(tok::annot_template_id) &&
+ NextToken().is(tok::coloncolon)) ||
+Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
   }
   bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
 return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2060,9 +2060,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5336,6 +5336,8 @@
 return isDeclarationSpecifier();
 
   case tok::coloncolon:   // ::foo::bar
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::n

[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-10-18 Thread Hu Jialun via Phabricator via cfe-commits
SuibianP updated this revision to Diff 468488.
SuibianP added a comment.

Remove superfluous parentheses


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133248/new/

https://reviews.llvm.org/D133248

Files:
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/Parser.cpp
  clang/test/Parser/c2x-attributes.c


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot 
appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as 
scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2080,9 +2080,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope 
either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5411,6 +5411,8 @@
 return isDeclarationSpecifier(AllowImplicitTypename);
 
   case tok::coloncolon:   // ::foo::bar
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::new
 NextToken().is(tok::kw_delete))   // ::delete
   return false;
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -866,10 +866,11 @@
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
   bool MightBeCXXScopeToken() {
-return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
-   (Tok.is(tok::annot_template_id) &&
-NextToken().is(tok::coloncolon)) ||
-   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+return getLangOpts().CPlusPlus &&
+   (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+(Tok.is(tok::annot_template_id) &&
+ NextToken().is(tok::coloncolon)) ||
+Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
   }
   bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
 return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2080,9 +2080,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5411,6 +5411,8 @@
 return isDeclarationSpecifier(AllowImplicitTypename);
 
   case tok::coloncolon:   // ::foo::bar
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::new
 NextToken().is(tok::kw_delete))   // ::delete
   return false;
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -866,10 +866,11 @@
   bool TryAnnotateCXXScopeToken(

[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-10-18 Thread Hu Jialun via Phabricator via cfe-commits
SuibianP updated this revision to Diff 468509.
SuibianP added a comment.

Add release note entry


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133248/new/

https://reviews.llvm.org/D133248

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/Parser.cpp
  clang/test/Parser/c2x-attributes.c


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot 
appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as 
scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2080,9 +2080,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope 
either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5411,6 +5411,8 @@
 return isDeclarationSpecifier(AllowImplicitTypename);
 
   case tok::coloncolon:   // ::foo::bar
+if (!getLangOpts().CPlusPlus)
+  return false;
 if (NextToken().is(tok::kw_new) ||// ::new
 NextToken().is(tok::kw_delete))   // ::delete
   return false;
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -866,10 +866,11 @@
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
   bool MightBeCXXScopeToken() {
-return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
-   (Tok.is(tok::annot_template_id) &&
-NextToken().is(tok::coloncolon)) ||
-   Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+return getLangOpts().CPlusPlus &&
+   (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+(Tok.is(tok::annot_template_id) &&
+ NextToken().is(tok::coloncolon)) ||
+Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
   }
   bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
 return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -251,6 +251,7 @@
 - Address the thread identification problems in coroutines.
   `Issue 47177 `_
   `Issue 47179 `_
+- Fix a crash upon stray coloncolon token in C2x mode.
 
 Improvements to Clang's diagnostics
 ^^^


Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -141,3 +141,6 @@
 struct [[]] S4 *s; // expected-error {{an attribute list cannot appear here}}
 struct S5 {};
 int c = sizeof(struct [[]] S5); // expected-error {{an attribute list cannot appear here}}
+
+// Ensure that '::' outside of attributes does not crash and is not treated as scope
+double n::v; // expected-error {{expected ';' after top level declarator}}
Index: clang/lib/Parse/Parser.cpp
===
--- clang/lib/Parse/Parser.cpp
+++ clang/lib/Parse/Parser.cpp
@@ -2080,9 +2080,9 @@
 }
 
 if (!getLangOpts().CPlusPlus) {
-  // If we're in C, we can't have :: tokens at all (the lexer won't return
-  // them).  If the identifier is not a type, then it can't be scope either,
-  // just early exit.
+  // If we're in C, the only place we can have :: tokens is C2x
+  // attribute which is parsed elsewhere. If the identifier is not a type,
+  // then it can't be scope either, just early exit.
   return false;
 }
 
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5411,

[PATCH] D133248: [clang] Fix crash upon stray coloncolon token in C2x mode

2022-10-18 Thread Hu Jialun via Phabricator via cfe-commits
SuibianP added a comment.

@aaron.ballman Thanks for the guidance! I have rectified the parentheses and 
appended to the release notes. Please feel free to point out any additional 
issues with the Differential.

If all is good, I would like to have the patch attributed to `Jialun Hu 
`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133248/new/

https://reviews.llvm.org/D133248

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits