Skip to content

Commit 5a48b97

Browse files
committed
[Clang] prevent crash on unterminated __has_embed
1 parent 4bf5ab4 commit 5a48b97

File tree

4 files changed

+16
-10
lines changed

4 files changed

+16
-10
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ Bug Fixes in This Version
405405
a function without arguments caused us to try to access a non-existent argument.
406406
(#GH159080)
407407
- Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898)
408+
- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
408409

409410
Bug Fixes to Compiler Builtins
410411
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Lex/PPDirectives.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3648,14 +3648,14 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
36483648
std::pair<tok::TokenKind, SourceLocation> Matches) {
36493649
Diag(CurTok, diag::err_expected) << Expected;
36503650
Diag(Matches.second, diag::note_matching) << Matches.first;
3651-
if (CurTok.isNot(tok::eod))
3651+
if (CurTok.isNot(EndTokenKind))
36523652
DiscardUntilEndOfDirective(CurTok);
36533653
};
36543654

36553655
auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) {
36563656
if (CurTok.isNot(Kind)) {
36573657
Diag(CurTok, diag::err_expected) << Kind;
3658-
if (CurTok.isNot(tok::eod))
3658+
if (CurTok.isNot(EndTokenKind))
36593659
DiscardUntilEndOfDirective(CurTok);
36603660
return false;
36613661
}
@@ -3746,7 +3746,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
37463746
if (Result.isNegative()) {
37473747
Diag(CurTok, diag::err_requires_positive_value)
37483748
<< toString(Result, 10) << /*positive*/ 0;
3749-
if (CurTok.isNot(tok::eod))
3749+
if (CurTok.isNot(EndTokenKind))
37503750
DiscardUntilEndOfDirective(CurTok);
37513751
return std::nullopt;
37523752
}
@@ -3889,7 +3889,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
38893889
}
38903890
if (!ForHasEmbed) {
38913891
Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 << Parameter;
3892-
if (CurTok.isNot(tok::eod))
3892+
if (CurTok.isNot(EndTokenKind))
38933893
DiscardUntilEndOfDirective(CurTok);
38943894
return std::nullopt;
38953895
}

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,16 +1262,11 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) {
12621262

12631263
std::optional<LexEmbedParametersResult> Params =
12641264
this->LexEmbedParameters(Tok, /*ForHasEmbed=*/true);
1265-
assert((Params || Tok.is(tok::eod)) &&
1266-
"expected success or to be at the end of the directive");
12671265

12681266
if (!Params)
12691267
return EmbedResult::Invalid;
12701268

1271-
if (Params->UnrecognizedParams > 0)
1272-
return EmbedResult::NotFound;
1273-
1274-
if (!Tok.is(tok::r_paren)) {
1269+
if (Tok.isNot(tok::r_paren)) {
12751270
Diag(this->getLocForEndOfToken(FilenameLoc), diag::err_pp_expected_after)
12761271
<< II << tok::r_paren;
12771272
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
@@ -1280,6 +1275,9 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) {
12801275
return EmbedResult::Invalid;
12811276
}
12821277

1278+
if (Params->UnrecognizedParams > 0)
1279+
return EmbedResult::NotFound;
1280+
12831281
SmallString<128> FilenameBuffer;
12841282
StringRef Filename = this->getSpelling(FilenameTok, FilenameBuffer);
12851283
if (Filename.empty())

clang/test/Preprocessor/embed___has_embed_parsing_errors.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,10 @@
250250

251251
#if __has_embed("") // expected-error {{empty filename}}
252252
#endif
253+
254+
// expected-error@+4 {{missing ')' after '__has_embed'}} \
255+
expected-error@+4 {{expected value in expression}} \
256+
expected-error@+4 {{unterminated conditional directive}} \
257+
expected-note@+4 {{to match this '('}}
258+
#if __has_embed (__FILE__ limit(1) foo
259+
int a = __has_embed (__FILE__);

0 commit comments

Comments
 (0)