Skip to content

[flang] Don't perform macro replacement on exponents #136176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions flang/include/flang/Parser/token-sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ class Prescanner;
class TokenSequence {
public:
TokenSequence() {}
TokenSequence(const TokenSequence &that) { Put(that); }
TokenSequence(const TokenSequence &that) { CopyAll(that); }
TokenSequence(
const TokenSequence &that, std::size_t at, std::size_t count = 1) {
Put(that, at, count);
AppendRange(that, at, count);
}
TokenSequence(TokenSequence &&that)
: start_{std::move(that.start_)}, nextStart_{that.nextStart_},
Expand All @@ -48,7 +48,7 @@ class TokenSequence {

TokenSequence &operator=(const TokenSequence &that) {
clear();
Put(that);
CopyAll(that);
return *this;
}
TokenSequence &operator=(TokenSequence &&that);
Expand Down Expand Up @@ -100,14 +100,26 @@ class TokenSequence {
start_.pop_back();
}

void Put(const TokenSequence &);
void Put(const TokenSequence &, ProvenanceRange);
void Put(const TokenSequence &, std::size_t at, std::size_t tokens = 1);
// These append characters with provenance and then close the token.
// When the last token of this sequence remains open beforehand,
// the new characters are appended to it.
void Put(const char *, std::size_t, Provenance);
void Put(const CharBlock &, Provenance);
void Put(const std::string &, Provenance);
void Put(llvm::raw_string_ostream &, Provenance);

// Appends a full copy of another sequence. When the last token of this
// sequence remains open beforehand, it is closed before the new text
// is appended.
void CopyAll(const TokenSequence &);
// Copies a range of tokens from another sequence. If the last token of
// this sequence remains open, the first token of the copied range will be
// appended to it.
void AppendRange(
const TokenSequence &, std::size_t at, std::size_t tokens = 1);
// Copies tokens (via Put above) with new provenance.
void CopyWithProvenance(const TokenSequence &, ProvenanceRange);

Provenance GetCharProvenance(std::size_t) const;
Provenance GetTokenProvenance(
std::size_t token, std::size_t offset = 0) const;
Expand Down
38 changes: 19 additions & 19 deletions flang/lib/Parser/preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ TokenSequence Definition::Tokenize(const std::vector<std::string> &argNames,
continue;
}
}
result.Put(token, firstToken + j, 1);
result.AppendRange(token, firstToken + j, 1);
}
return result;
}
Expand Down Expand Up @@ -170,7 +170,7 @@ static TokenSequence TokenPasting(TokenSequence &&text) {
}
} else if (pasting && text.TokenAt(j).IsBlank()) {
} else {
result.Put(text, j, 1);
result.AppendRange(text, j, 1);
pasting = false;
}
}
Expand Down Expand Up @@ -223,7 +223,7 @@ TokenSequence Definition::Apply(const std::vector<TokenSequence> &args,
CHECK(resultSize > 0 &&
result.TokenAt(resultSize - 1) == replacement_.TokenAt(prev - 1));
result.pop_back();
result.Put(Stringify(args[index], prescanner.allSources()));
result.CopyAll(Stringify(args[index], prescanner.allSources()));
} else {
const TokenSequence *arg{&args[index]};
std::optional<TokenSequence> replaced;
Expand All @@ -243,7 +243,7 @@ TokenSequence Definition::Apply(const std::vector<TokenSequence> &args,
}
}
}
result.Put(DEREF(arg));
result.CopyAll(DEREF(arg));
}
} else if (bytes == 11 && isVariadic_ &&
token.ToString() == "__VA_ARGS__") {
Expand All @@ -254,7 +254,7 @@ TokenSequence Definition::Apply(const std::vector<TokenSequence> &args,
if (k > argumentCount()) {
result.Put(","s, commaProvenance);
}
result.Put(args[k]);
result.CopyAll(args[k]);
}
} else if (bytes == 10 && isVariadic_ && token.ToString() == "__VA_OPT__" &&
j + 2 < tokens && replacement_.TokenAt(j + 1).OnlyNonBlank() == '(' &&
Expand All @@ -274,7 +274,7 @@ TokenSequence Definition::Apply(const std::vector<TokenSequence> &args,
}
}
}
result.Put(replacement_, j);
result.AppendRange(replacement_, j);
}
}
return TokenPasting(std::move(result));
Expand Down Expand Up @@ -338,18 +338,18 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
inIfExpression](std::size_t after, const TokenSequence &replacement,
std::size_t pFLMOffset) {
if (after < input.SizeInTokens()) {
result.Put(replacement, 0, pFLMOffset);
result.AppendRange(replacement, 0, pFLMOffset);
TokenSequence suffix;
suffix.Put(
suffix.AppendRange(
replacement, pFLMOffset, replacement.SizeInTokens() - pFLMOffset);
suffix.Put(input, after, input.SizeInTokens() - after);
suffix.AppendRange(input, after, input.SizeInTokens() - after);
auto further{ReplaceMacros(
suffix, prescanner, partialFunctionLikeMacro, inIfExpression)};
if (partialFunctionLikeMacro && *partialFunctionLikeMacro) {
// still not closed
**partialFunctionLikeMacro += result.SizeInTokens();
}
result.Put(further);
result.CopyAll(further);
return true;
} else {
if (partialFunctionLikeMacro) {
Expand All @@ -362,7 +362,7 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
for (; j < tokens; ++j) {
CharBlock token{input.TokenAt(j)};
if (token.IsBlank() || !IsLegalIdentifierStart(token[0])) {
result.Put(input, j);
result.AppendRange(input, j);
continue;
}
// Process identifier in replacement text.
Expand All @@ -388,12 +388,12 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
}
}
if (it == definitions_.end()) {
result.Put(input, j);
result.AppendRange(input, j);
continue;
}
Definition *def{&it->second};
if (def->isDisabled()) {
result.Put(input, j);
result.AppendRange(input, j);
continue;
}
if (!def->isFunctionLike()) {
Expand Down Expand Up @@ -444,7 +444,7 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
ProvenanceRange use{input.GetTokenProvenanceRange(j)};
ProvenanceRange newRange{
allSources_.AddMacroCall(from, use, replaced.ToString())};
result.Put(replaced, newRange);
result.CopyWithProvenance(replaced, newRange);
}
} else {
// Possible function-like macro call. Skip spaces and newlines to see
Expand All @@ -461,10 +461,10 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
if (!leftParen) {
if (partialFunctionLikeMacro) {
*partialFunctionLikeMacro = result.SizeInTokens();
result.Put(input, j, tokens - j);
result.AppendRange(input, j, tokens - j);
return result;
} else {
result.Put(input, j);
result.AppendRange(input, j);
continue;
}
}
Expand All @@ -491,11 +491,11 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
}
if (k >= tokens && partialFunctionLikeMacro) {
*partialFunctionLikeMacro = result.SizeInTokens();
result.Put(input, j, tokens - j);
result.AppendRange(input, j, tokens - j);
return result;
} else if (k >= tokens || argStart.size() < def->argumentCount() ||
(argStart.size() > def->argumentCount() && !def->isVariadic())) {
result.Put(input, j);
result.AppendRange(input, j);
continue;
}
std::vector<TokenSequence> args;
Expand All @@ -520,7 +520,7 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
ProvenanceRange use{input.GetIntervalProvenanceRange(j, k - j)};
ProvenanceRange newRange{
allSources_.AddMacroCall(from, use, replaced.ToString())};
result.Put(replaced, newRange);
result.CopyWithProvenance(replaced, newRange);
}
j = k; // advance to the terminal ')'
}
Expand Down
13 changes: 6 additions & 7 deletions flang/lib/Parser/prescan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,8 +903,7 @@ bool Prescanner::HandleExponent(TokenSequence &tokens) {
EmitCharAndAdvance(possible, *at_);
}
possible.CloseToken();
tokens.CloseToken();
tokens.Put(possible);
tokens.AppendRange(possible, 0); // appends to current token
return true;
}
// Not an exponent; backtrack
Expand Down Expand Up @@ -937,9 +936,9 @@ bool Prescanner::HandleKindSuffix(TokenSequence &tokens) {
preprocessor_.IsNameDefined(separate.TokenAt(1)) &&
!preprocessor_.IsNameDefined(withUnderscore.ToCharBlock())) {
// "_foo" is not defined, but "foo" is
tokens.Put(separate); // '_' "foo"
tokens.CopyAll(separate); // '_' "foo"
} else {
tokens.Put(withUnderscore); // "_foo"
tokens.CopyAll(withUnderscore); // "_foo"
}
return true;
}
Expand Down Expand Up @@ -1011,7 +1010,7 @@ void Prescanner::QuotedCharacterLiteral(
ppTokens.Put(id, GetProvenance(idStart));
if (auto replaced{
preprocessor_.MacroReplacement(ppTokens, *this)}) {
tokens.Put(*replaced);
tokens.CopyAll(*replaced);
at_ = &idStart[idLen - 1];
NextLine();
continue; // try again on the next line
Expand Down Expand Up @@ -1812,7 +1811,7 @@ bool Prescanner::CompilerDirectiveContinuation(
}
if (ok) {
tokens.pop_back(); // delete original '&'
tokens.Put(followingTokens, startAt, following - startAt);
tokens.AppendRange(followingTokens, startAt, following - startAt);
tokens.RemoveRedundantBlanks();
} else {
nextLine_ = origNextLine;
Expand Down Expand Up @@ -1842,7 +1841,7 @@ bool Prescanner::SourceLineContinuation(TokenSequence &tokens) {
}
followingTokens.RemoveRedundantBlanks();
tokens.pop_back(); // delete original '&'
tokens.Put(followingTokens);
tokens.CopyAll(followingTokens);
return true;
}
}
Expand Down
13 changes: 7 additions & 6 deletions flang/lib/Parser/token-sequence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ bool TokenSequence::IsAnythingLeft(std::size_t at) const {
return false;
}

void TokenSequence::Put(const TokenSequence &that) {
void TokenSequence::CopyAll(const TokenSequence &that) {
if (nextStart_ < char_.size()) {
start_.push_back(nextStart_);
}
Expand All @@ -109,7 +109,8 @@ void TokenSequence::Put(const TokenSequence &that) {
provenances_.Put(that.provenances_);
}

void TokenSequence::Put(const TokenSequence &that, ProvenanceRange range) {
void TokenSequence::CopyWithProvenance(
const TokenSequence &that, ProvenanceRange range) {
std::size_t offset{0};
std::size_t tokens{that.SizeInTokens()};
for (std::size_t j{0}; j < tokens; ++j) {
Expand All @@ -120,7 +121,7 @@ void TokenSequence::Put(const TokenSequence &that, ProvenanceRange range) {
CHECK(offset == range.size());
}

void TokenSequence::Put(
void TokenSequence::AppendRange(
const TokenSequence &that, std::size_t at, std::size_t tokens) {
ProvenanceRange provenance;
std::size_t offset{0};
Expand Down Expand Up @@ -246,7 +247,7 @@ TokenSequence &TokenSequence::RemoveBlanks(std::size_t firstChar) {
TokenSequence result;
for (std::size_t j{0}; j < tokens; ++j) {
if (!TokenAt(j).IsBlank() || start_[j] < firstChar) {
result.Put(*this, j);
result.AppendRange(*this, j);
}
}
swap(result);
Expand All @@ -260,7 +261,7 @@ TokenSequence &TokenSequence::RemoveRedundantBlanks(std::size_t firstChar) {
for (std::size_t j{0}; j < tokens; ++j) {
bool isBlank{TokenAt(j).IsBlank()};
if (!isBlank || !lastWasBlank || start_[j] < firstChar) {
result.Put(*this, j);
result.AppendRange(*this, j);
}
lastWasBlank = isBlank;
}
Expand Down Expand Up @@ -294,7 +295,7 @@ TokenSequence &TokenSequence::ClipComment(
} else {
TokenSequence result;
if (j > 0) {
result.Put(*this, 0, j - 1);
result.AppendRange(*this, 0, j - 1);
}
swap(result);
return *this;
Expand Down
5 changes: 5 additions & 0 deletions flang/test/Preprocessing/exponent-bug.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
! RUN: %flang -E %s 2>&1 | FileCheck %s
! CHECK: 3.14159e00
#define e00 e666
print *, 3.14159e00
end
Loading