Skip to content

Commit d4ee050

Browse files
authored
[Parse] Fix nested ifConfig compiler checks (#74415)
The parser is supposed to avoid looking inside unmatched `#if` compiler (et al) blocks. This usually means that the following code builds fine #if compiler(>=100) foo bar #endif however, a logical bug meant that if the check was nested inside an already-inactive `#if` block, it would not adhere to this evaluation-skipping behavior #if false #if compiler(>=100) foo bar // error! #endif #endif This PR fixes this specific case.
1 parent 7798926 commit d4ee050

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lib/Parse/ParseIfConfig.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -843,10 +843,16 @@ Result Parser::parseIfConfigRaw(
843843
// Error in the condition;
844844
isActive = false;
845845
isVersionCondition = false;
846-
} else if (!foundActive && shouldEvaluate) {
846+
} else if (!foundActive) {
847847
// Evaluate the condition only if we haven't found any active one and
848848
// we're not in parse-only mode.
849-
isActive = evaluateIfConfigCondition(Condition, Context);
849+
if (shouldEvaluate) {
850+
isActive = evaluateIfConfigCondition(Condition, Context);
851+
}
852+
// Determine isVersionCondition regardless of whether we're active.
853+
// This is necessary in some edge cases, e.g. where we're in a nested,
854+
// inactive #if block, and we encounter an inactive `#if compiler` check,
855+
// as we have to explicitly skip parsing in such edge cases.
850856
isVersionCondition = isVersionIfConfigCondition(Condition);
851857
}
852858
}

test/Parse/ConditionalCompilation/compiler.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,21 @@
2828
// There should be no error here.
2929
foo bar
3030
#endif
31+
32+
#if compiler(>=4.1)
33+
let _: Int = 1
34+
#else
35+
#if false
36+
// There should be no error here.
37+
foo bar
38+
#endif
39+
#endif
40+
41+
#if false
42+
#if compiler(>=4.1)
43+
let _: Int = 1
44+
#else
45+
// There should be no error here.
46+
foo bar
47+
#endif
48+
#endif

0 commit comments

Comments
 (0)