forked from OSchip/llvm-project
[clang] better error message for while loops outside of control flow
report an error when encountering 'while' token parsing declarator ``` clang/test/Parser/while-loop-outside-function.c:3:1: error: while loop outside of a function while // expected-error {{while loop outside of a function}} ^ clang/test/Parser/while-loop-outside-function.c:7:1: error: while loop outside of a function while // expected-error {{while loop outside of a function}} ^ ``` Fixes: https://github.com/llvm/llvm-project/issues/34462 Differential Revision: https://reviews.llvm.org/D129573
This commit is contained in:
parent
1ef32e7828
commit
edaae251cc
|
@ -538,6 +538,8 @@ def err_invalid_operator_on_type : Error<
|
||||||
"cannot use %select{dot|arrow}0 operator on a type">;
|
"cannot use %select{dot|arrow}0 operator on a type">;
|
||||||
def err_expected_unqualified_id : Error<
|
def err_expected_unqualified_id : Error<
|
||||||
"expected %select{identifier|unqualified-id}0">;
|
"expected %select{identifier|unqualified-id}0">;
|
||||||
|
def err_while_loop_outside_of_a_function : Error<
|
||||||
|
"while loop outside of a function">;
|
||||||
def err_brackets_go_after_unqualified_id : Error<
|
def err_brackets_go_after_unqualified_id : Error<
|
||||||
"brackets are not allowed here; to declare an array, "
|
"brackets are not allowed here; to declare an array, "
|
||||||
"place the brackets after the %select{identifier|name}0">;
|
"place the brackets after the %select{identifier|name}0">;
|
||||||
|
|
|
@ -6344,23 +6344,27 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||||
diag::err_expected_member_name_or_semi)
|
diag::err_expected_member_name_or_semi)
|
||||||
<< (D.getDeclSpec().isEmpty() ? SourceRange()
|
<< (D.getDeclSpec().isEmpty() ? SourceRange()
|
||||||
: D.getDeclSpec().getSourceRange());
|
: D.getDeclSpec().getSourceRange());
|
||||||
} else if (getLangOpts().CPlusPlus) {
|
|
||||||
if (Tok.isOneOf(tok::period, tok::arrow))
|
|
||||||
Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
|
|
||||||
else {
|
|
||||||
SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
|
|
||||||
if (Tok.isAtStartOfLine() && Loc.isValid())
|
|
||||||
Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
|
|
||||||
<< getLangOpts().CPlusPlus;
|
|
||||||
else
|
|
||||||
Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
|
|
||||||
diag::err_expected_unqualified_id)
|
|
||||||
<< getLangOpts().CPlusPlus;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
|
if (Tok.getKind() == tok::TokenKind::kw_while) {
|
||||||
diag::err_expected_either)
|
Diag(Tok, diag::err_while_loop_outside_of_a_function);
|
||||||
<< tok::identifier << tok::l_paren;
|
} else if (getLangOpts().CPlusPlus) {
|
||||||
|
if (Tok.isOneOf(tok::period, tok::arrow))
|
||||||
|
Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
|
||||||
|
else {
|
||||||
|
SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
|
||||||
|
if (Tok.isAtStartOfLine() && Loc.isValid())
|
||||||
|
Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
|
||||||
|
<< getLangOpts().CPlusPlus;
|
||||||
|
else
|
||||||
|
Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
|
||||||
|
diag::err_expected_unqualified_id)
|
||||||
|
<< getLangOpts().CPlusPlus;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
|
||||||
|
diag::err_expected_either)
|
||||||
|
<< tok::identifier << tok::l_paren;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
D.SetIdentifier(nullptr, Tok.getLocation());
|
D.SetIdentifier(nullptr, Tok.getLocation());
|
||||||
D.setInvalidType(true);
|
D.setInvalidType(true);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||||
|
|
||||||
|
while // expected-error {{while loop outside of a function}}
|
||||||
|
(1) {};
|
||||||
|
|
||||||
|
// without semicolon
|
||||||
|
while // expected-error {{while loop outside of a function}}
|
||||||
|
(1) {}
|
||||||
|
|
||||||
|
int overload_return(); // expected-note {{previous declaration is here}}
|
||||||
|
|
||||||
|
void overload_return() // expected-error {{conflicting types for 'overload_return'}}
|
||||||
|
{
|
||||||
|
while(1) {};
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while // expected-error {{while loop outside of a function}}
|
||||||
|
(1);
|
||||||
|
|
||||||
|
void correct();
|
||||||
|
|
||||||
|
void correct() {
|
||||||
|
while(1) {};
|
||||||
|
while(1);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||||
|
|
||||||
|
while // expected-error {{while loop outside of a function}}
|
||||||
|
(true) {};
|
||||||
|
|
||||||
|
// without semicolon
|
||||||
|
while // expected-error {{while loop outside of a function}}
|
||||||
|
(true) {}
|
||||||
|
|
||||||
|
do { // expected-error {{expected unqualified-id}}
|
||||||
|
int some_var = 1;
|
||||||
|
some_var += 3;
|
||||||
|
}
|
||||||
|
while // expected-error {{while loop outside of a function}}
|
||||||
|
(true);
|
||||||
|
|
||||||
|
void someFunction() {
|
||||||
|
while(true) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
class SomeClass {
|
||||||
|
public:
|
||||||
|
while(true) {} // expected-error {{expected member name or ';' after declaration specifiers}}
|
||||||
|
void some_fn() {
|
||||||
|
while(true) {}
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue