Skip to content
Merged
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ Bug Fixes in This Version
a function without arguments caused us to try to access a non-existent argument.
(#GH159080)
- Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898)
- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Lex/PPDirectives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3648,14 +3648,14 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
std::pair<tok::TokenKind, SourceLocation> Matches) {
Diag(CurTok, diag::err_expected) << Expected;
Diag(Matches.second, diag::note_matching) << Matches.first;
if (CurTok.isNot(tok::eod))
if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
};

auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) {
if (CurTok.isNot(Kind)) {
Diag(CurTok, diag::err_expected) << Kind;
if (CurTok.isNot(tok::eod))
if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
return false;
}
Expand Down Expand Up @@ -3746,7 +3746,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
if (Result.isNegative()) {
Diag(CurTok, diag::err_requires_positive_value)
<< toString(Result, 10) << /*positive*/ 0;
if (CurTok.isNot(tok::eod))
if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
return std::nullopt;
}
Expand Down Expand Up @@ -3889,7 +3889,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
}
if (!ForHasEmbed) {
Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 << Parameter;
if (CurTok.isNot(tok::eod))
if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
return std::nullopt;
}
Expand Down
10 changes: 4 additions & 6 deletions clang/lib/Lex/PPMacroExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1262,16 +1262,11 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) {

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

if (!Params)
return EmbedResult::Invalid;

if (Params->UnrecognizedParams > 0)
return EmbedResult::NotFound;

if (!Tok.is(tok::r_paren)) {
if (Tok.isNot(tok::r_paren)) {
Diag(this->getLocForEndOfToken(FilenameLoc), diag::err_pp_expected_after)
<< II << tok::r_paren;
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
Expand All @@ -1280,6 +1275,9 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) {
return EmbedResult::Invalid;
}

if (Params->UnrecognizedParams > 0)
return EmbedResult::NotFound;

SmallString<128> FilenameBuffer;
StringRef Filename = this->getSpelling(FilenameTok, FilenameBuffer);
if (Filename.empty())
Expand Down
7 changes: 7 additions & 0 deletions clang/test/Preprocessor/embed___has_embed_parsing_errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,10 @@

#if __has_embed("") // expected-error {{empty filename}}
#endif

// expected-error@+4 {{missing ')' after '__has_embed'}} \
expected-error@+4 {{expected value in expression}} \
expected-error@+4 {{unterminated conditional directive}} \
expected-note@+4 {{to match this '('}}
#if __has_embed (__FILE__ limit(1) foo
int a = __has_embed (__FILE__);