Skip to content

Commit 43ec3fe

Browse files
committed
Clang/Preprocessor: Support short circuit in directive
Don't Evaluate RHS in if directive when short circuit. Examples include #if 0 && another_condition #if 1 || another_condition
1 parent 76b0187 commit 43ec3fe

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

clang/lib/Lex/PPExpressions.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,33 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
624624

625625
// Consume the operator, remembering the operator's location for reporting.
626626
SourceLocation OpLoc = PeekTok.getLocation();
627-
PP.LexNonComment(PeekTok);
627+
628+
if (!RHSIsLive && (Operator == tok::ampamp || Operator == tok::pipepipe)) {
629+
unsigned ThisPrec = PeekPrec;
630+
while (true) {
631+
PP.LexUnexpandedNonComment(PeekTok);
632+
if (PeekTok.is(tok::l_paren)) {
633+
unsigned NestParen = 1;
634+
while (true) {
635+
PP.LexUnexpandedNonComment(PeekTok);
636+
if (PeekTok.is(tok::l_paren))
637+
NestParen++;
638+
else if (PeekTok.is(tok::r_paren))
639+
NestParen--;
640+
if (NestParen == 0)
641+
break;
642+
}
643+
PP.LexUnexpandedNonComment(PeekTok);
644+
}
645+
PeekPrec = getPrecedence(PeekTok.getKind());
646+
if (PeekPrec <= ThisPrec) {
647+
LHS.setEnd(PeekTok.getEndLoc());
648+
break;
649+
}
650+
}
651+
continue;
652+
} else
653+
PP.LexNonComment(PeekTok);
628654

629655
PPValue RHS(LHS.getBitWidth());
630656
// Parse the RHS of the operator.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// RUN: %clang -E -MD -MF - %s | FileCheck -check-prefix ZERO_AND_HAS_INCLUDE %s
2+
//
3+
// ZERO_AND_HAS_INCLUDE-NOT: limits.h
4+
//
5+
#if 0 && __has_include(<limits.h>)
6+
#include <limits.h>
7+
#endif
8+
9+
#if 4==5 && __has_include(<limits.h>)
10+
#include <limits.h>
11+
#endif
12+
13+
#if defined(_THIS_IS_NOT_DEFINED) && __has_include(<limits.h>)
14+
#include <limits.h>
15+
#endif
16+
17+
#if 0 && (__has_include(<limits.h>))
18+
#include <limits.h>
19+
#endif
20+
21+
#if 4==5 && (__has_include(<limits.h>))
22+
#include <limits.h>
23+
#endif
24+
25+
#if defined(_THIS_IS_NOT_DEFINED) && (__has_include(<limits.h>))
26+
#include <limits.h>
27+
#endif
28+
29+
#if 0 && (5==5 && __has_include(<limits.h>))
30+
#include <limits.h>
31+
#endif
32+
33+
#if 1 && (4==5 && __has_include(<limits.h>))
34+
#include <limits.h>
35+
#endif
36+
37+
38+
39+
40+
41+
42+
#if 1 || __has_include(<limits.h>)
43+
XXXXXXXXXX
44+
#endif
45+
#if 5==5 || __has_include(<limits.h>)
46+
XXXXXXXXXX
47+
#endif
48+
49+
#if defined(__clang__) || __has_include(<limits.h>)
50+
XXXXXXXXXX
51+
#endif
52+
53+
#if 1 || (__has_include(<limits.h>))
54+
#endif
55+
56+
#if 5==5 || (__has_include(<limits.h>))
57+
XXXXXXXXXX
58+
#endif
59+
60+
#if defined(__clang__) || (__has_include(<limits.h>))
61+
XXXXXXXXXX
62+
#endif
63+
64+
#if 1 && (5==5 || __has_include(<limits.h>))
65+
XXXXXXXXXX
66+
#endif
67+
68+
#if 1 || (5==5 || __has_include(<limits.h>))
69+
XXXXXXXXXX
70+
#endif
71+
72+
#if 0 || (5==5 || __has_include(<limits.h>))
73+
XXXXXXXXXX
74+
#endif

0 commit comments

Comments
 (0)