https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/123912
>From f0010f932ae3c89651c631736a7aa495027e8fdc Mon Sep 17 00:00:00 2001 From: YunQiang Su <yunqi...@isrc.iscas.ac.cn> Date: Wed, 22 Jan 2025 09:04:44 +0000 Subject: [PATCH] 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 --- clang/lib/Lex/PPExpressions.cpp | 28 ++++++- clang/test/C/drs/dr2xx.c | 2 +- ...wavefront-size-deprecation-diagnostics.hip | 2 +- .../Preprocessor/directive-short-circuit.c | 74 +++++++++++++++++++ 4 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 clang/test/Preprocessor/directive-short-circuit.c diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index a3b1384f0fa1d6..7e413ec6076642 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -624,7 +624,33 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // Consume the operator, remembering the operator's location for reporting. SourceLocation OpLoc = PeekTok.getLocation(); - PP.LexNonComment(PeekTok); + + if (!RHSIsLive && (Operator == tok::ampamp || Operator == tok::pipepipe)) { + unsigned ThisPrec = PeekPrec; + while (true) { + PP.LexUnexpandedNonComment(PeekTok); + if (PeekTok.is(tok::l_paren)) { + unsigned NestParen = 1; + while (true) { + PP.LexUnexpandedNonComment(PeekTok); + if (PeekTok.is(tok::l_paren)) + NestParen++; + else if (PeekTok.is(tok::r_paren)) + NestParen--; + if (NestParen == 0) + break; + } + PP.LexUnexpandedNonComment(PeekTok); + } + PeekPrec = getPrecedence(PeekTok.getKind()); + if (PeekPrec <= ThisPrec) { + LHS.setEnd(PeekTok.getEndLoc()); + break; + } + } + continue; + } else + PP.LexNonComment(PeekTok); PPValue RHS(LHS.getBitWidth()); // Parse the RHS of the operator. diff --git a/clang/test/C/drs/dr2xx.c b/clang/test/C/drs/dr2xx.c index ffdf5aac377d97..a1e24257f2e8ed 100644 --- a/clang/test/C/drs/dr2xx.c +++ b/clang/test/C/drs/dr2xx.c @@ -258,7 +258,7 @@ void dr252(void) { void dr258(void) { /* We get the diagnostic twice because the argument is used twice in the * expansion. */ -#define repeat(x) x && x +#define repeat(x) x || x #if repeat(defined fred) /* expected-warning 2 {{macro expansion producing 'defined' has undefined behavior}} */ #endif diff --git a/clang/test/Driver/hip-wavefront-size-deprecation-diagnostics.hip b/clang/test/Driver/hip-wavefront-size-deprecation-diagnostics.hip index 8a60f5a150048f..dcd0b4f6f9fdd6 100644 --- a/clang/test/Driver/hip-wavefront-size-deprecation-diagnostics.hip +++ b/clang/test/Driver/hip-wavefront-size-deprecation-diagnostics.hip @@ -23,7 +23,7 @@ template<int N> __attribute__((host, device)) int templatify(int x) { __attribute__((device)) const int GlobalConst = __AMDGCN_WAVEFRONT_SIZE__; // expected-warning {{macro '__AMDGCN_WAVEFRONT_SIZE__' has been marked as deprecated}} constexpr int GlobalConstExpr = __AMDGCN_WAVEFRONT_SIZE__; // expected-warning {{macro '__AMDGCN_WAVEFRONT_SIZE__' has been marked as deprecated}} -#if defined(__HIP_DEVICE_COMPILE__) && (__AMDGCN_WAVEFRONT_SIZE__ == 64) // expected-warning {{macro '__AMDGCN_WAVEFRONT_SIZE__' has been marked as deprecated}} +#if (__AMDGCN_WAVEFRONT_SIZE__ == 64) && defined(__HIP_DEVICE_COMPILE__) // expected-warning {{macro '__AMDGCN_WAVEFRONT_SIZE__' has been marked as deprecated}} int foo(void); #endif diff --git a/clang/test/Preprocessor/directive-short-circuit.c b/clang/test/Preprocessor/directive-short-circuit.c new file mode 100644 index 00000000000000..d137f8198cbbcf --- /dev/null +++ b/clang/test/Preprocessor/directive-short-circuit.c @@ -0,0 +1,74 @@ +// RUN: %clang -E -MD -MF - %s | FileCheck -check-prefix ZERO_AND_HAS_INCLUDE %s +// +// ZERO_AND_HAS_INCLUDE-NOT: limits.h +// +#if 0 && __has_include(<limits.h>) +#include <limits.h> +#endif + +#if 4==5 && __has_include(<limits.h>) +#include <limits.h> +#endif + +#if defined(_THIS_IS_NOT_DEFINED) && __has_include(<limits.h>) +#include <limits.h> +#endif + +#if 0 && (__has_include(<limits.h>)) +#include <limits.h> +#endif + +#if 4==5 && (__has_include(<limits.h>)) +#include <limits.h> +#endif + +#if defined(_THIS_IS_NOT_DEFINED) && (__has_include(<limits.h>)) +#include <limits.h> +#endif + +#if 0 && (5==5 && __has_include(<limits.h>)) +#include <limits.h> +#endif + +#if 1 && (4==5 && __has_include(<limits.h>)) +#include <limits.h> +#endif + + + + + + +#if 1 || __has_include(<limits.h>) +XXXXXXXXXX +#endif +#if 5==5 || __has_include(<limits.h>) +XXXXXXXXXX +#endif + +#if defined(__clang__) || __has_include(<limits.h>) +XXXXXXXXXX +#endif + +#if 1 || (__has_include(<limits.h>)) +#endif + +#if 5==5 || (__has_include(<limits.h>)) +XXXXXXXXXX +#endif + +#if defined(__clang__) || (__has_include(<limits.h>)) +XXXXXXXXXX +#endif + +#if 1 && (5==5 || __has_include(<limits.h>)) +XXXXXXXXXX +#endif + +#if 1 || (5==5 || __has_include(<limits.h>)) +XXXXXXXXXX +#endif + +#if 0 || (5==5 || __has_include(<limits.h>)) +XXXXXXXXXX +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits