Skip to content

Commit f2bf44b

Browse files
authored
[flang][preprocessor] Finesse disabling of function-like macros (#71589)
During function-like macro expansion in a standard C/C++ preprocessor, the macro being expanded is disabled from recursive macro expansion. The implementation in this compiler's preprocessor, however, was too broad; the macro expansion needs to be disabled for the "rescanning" phase only, not for actual argument expansion. (Also corrects an obsolete comment elsewhere that was noticed during reduction of an original test case.)
1 parent 9c1c56a commit f2bf44b

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

flang/lib/Parser/preprocessor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,9 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
397397
(n + 1 == argStart.size() ? k : argStart[n + 1] - 1) - at};
398398
args.emplace_back(TokenSequence(input, at, count));
399399
}
400+
TokenSequence applied{def->Apply(args, prescanner)};
400401
def->set_isDisabled(true);
401-
TokenSequence replaced{
402-
ReplaceMacros(def->Apply(args, prescanner), prescanner)};
402+
TokenSequence replaced{ReplaceMacros(std::move(applied), prescanner)};
403403
def->set_isDisabled(false);
404404
if (!replaced.empty()) {
405405
ProvenanceRange from{def->replacement().GetProvenanceRange()};

flang/lib/Semantics/check-call.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,11 +1285,15 @@ static void CheckAssociated(evaluate::ActualArguments &arguments,
12851285
return;
12861286
}
12871287
if (const auto &targetArg{arguments[1]}) {
1288-
// The standard requires that the POINTER= argument be a valid LHS for
1289-
// a pointer assignment when the TARGET= argument is present. This,
1290-
// perhaps unintentionally, excludes function results, including NULL(),
1291-
// from being used there, as well as INTENT(IN) dummy pointers.
1292-
// Allow this usage as a benign extension with a portability warning.
1288+
// The standard requires that the TARGET= argument, when present,
1289+
// be a valid RHS for a pointer assignment that has the POINTER=
1290+
// argument as its LHS. Some popular compilers misinterpret this
1291+
// requirement more strongly than necessary, and actually validate
1292+
// the POINTER= argument as if it were serving as the LHS of a pointer
1293+
// assignment. This, perhaps unintentionally, excludes function
1294+
// results, including NULL(), from being used there, as well as
1295+
// INTENT(IN) dummy pointers. Detect these conditions and emit
1296+
// portability warnings.
12931297
if (!evaluate::ExtractDataRef(*pointerExpr) &&
12941298
!evaluate::IsProcedurePointer(*pointerExpr)) {
12951299
context.messages().Say(pointerArg->sourceLocation(),
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
! RUN: %flang -E %s | FileCheck %s
2+
#define KWM a
3+
#define FLM(x) b FLM2(x) KWM c
4+
#define FLM2(x) d FLM(x) e
5+
! CHECK: a
6+
KWM
7+
! CHECK: b d FLM(y) e a c
8+
FLM(y)
9+
! CHECK: b d FLM(a) e a c
10+
FLM(KWM)
11+
! CHECK: b d FLM(b d FLM(y) e a c) e a c
12+
FLM(FLM(y))
13+
! CHECK: b d FLM(b d FLM(a) e a c) e a c
14+
FLM(FLM(KWM))

0 commit comments

Comments
 (0)