mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 22:06:06 +00:00
[clang] Fix crash upon stray coloncolon token in C2x mode
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` Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D133248
This commit is contained in:
parent
b0ded70ebf
commit
94e8bd002c
@ -251,6 +251,7 @@ Bug Fixes
|
||||
- Address the thread identification problems in coroutines.
|
||||
`Issue 47177 <https://github.com/llvm/llvm-project/issues/47177>`_
|
||||
`Issue 47179 <https://github.com/llvm/llvm-project/issues/47179>`_
|
||||
- Fix a crash upon stray coloncolon token in C2x mode.
|
||||
|
||||
Improvements to Clang's diagnostics
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -866,10 +866,11 @@ public:
|
||||
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);
|
||||
|
@ -5411,6 +5411,8 @@ bool Parser::isDeclarationSpecifier(
|
||||
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;
|
||||
|
@ -2080,9 +2080,9 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -141,3 +141,6 @@ void test_asm(void) {
|
||||
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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user