https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/134884
>From 2661b9381e0a182fb53a81c8bf66cecd51c73b0f Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Tue, 8 Apr 2025 13:17:32 -0400 Subject: [PATCH 1/2] Reject invalid integer constants in unevaluated preprocessor operands Clang was previously accepting invalid code like: #if 1 ? 1 : 999999999999999999999 #endif because the integer constant (which is too large to fit into any standard or extended integer type) was in an unevaluated branch of the conditional operator. Similar invalid code involving || or && was also accepted and is now rejected. Fixes #134658 --- clang/docs/ReleaseNotes.rst | 8 ++++++ clang/lib/Lex/PPExpressions.cpp | 5 ++-- clang/test/Preprocessor/constants.c | 40 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 clang/test/Preprocessor/constants.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f8f4dfbafb4f8..6c86406ef36db 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -351,6 +351,14 @@ Bug Fixes in This Version - Defining an integer literal suffix (e.g., ``LL``) before including ``<stdint.h>`` in a freestanding build no longer causes invalid token pasting when using the ``INTn_C`` macros. (#GH85995) +- Clang no longer accepts invalid integer constants which are too large to fit + into any (standard or extended) integer type when the constant is unevaluated. + Merely forming the token is sufficient to render the program invalid. Code + like this was previously accepted and is now rejected (#GH134658): + .. code-block:: c + + #if 1 ? 1 : 999999999999999999999 + #endif Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index b031571907441..6a6762828a20e 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -345,9 +345,8 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Parse the integer literal into Result. if (Literal.GetIntegerValue(Result.Val)) { // Overflow parsing integer literal. - if (ValueLive) - PP.Diag(PeekTok, diag::err_integer_literal_too_large) - << /* Unsigned */ 1; + PP.Diag(PeekTok, diag::err_integer_literal_too_large) + << /* Unsigned */ 1; Result.Val.setIsUnsigned(true); } else { // Set the signedness of the result to match whether there was a U suffix diff --git a/clang/test/Preprocessor/constants.c b/clang/test/Preprocessor/constants.c new file mode 100644 index 0000000000000..d6241a4f1ceee --- /dev/null +++ b/clang/test/Preprocessor/constants.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -E -verify %s + +// C++ [lex.icon]p4 and C 6.4.4.1p2 + 6.4.4.2p7 both require C and C++ to +// validate the integer constant value when converting a preprocessing token +// into a token for semantic analysis, even within the preprocessor itself. + +// Plain integer constant. +#if 999999999999999999999 // expected-error {{integer literal is too large to be represented in any integer type}} +#endif + +// These cases were previously incorrectly accepted. See GH134658. + +// Integer constant in an unevaluated branch of a conditional. +#if 1 ? 1 : 999999999999999999999 // expected-error {{integer literal is too large to be represented in any integer type}} +#endif + +// Integer constant in an unevaluated operand of a logical operator. +#if 0 && 999999999999999999999 // expected-error {{integer literal is too large to be represented in any integer type}} +#endif + +#if 1 || 999999999999999999999 // expected-error {{integer literal is too large to be represented in any integer type}} +#endif + +// Make sure we also catch it in an elif condition. +#if 0 +#elif 1 || 999999999999999999999 // expected-error {{integer literal is too large to be represented in any integer type}} +#endif + +// However, if the block is skipped entirely, then it doesn't matter how +// invalid the constant value is. +#if 0 +int x = 999999999999999999999; + +#if 999999999999999999999 +#endif + +#if 0 && 999999999999999999999 +#endif + +#endif >From a4329eec3ff4dc1d8a343637428f1a67d87e24e5 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Tue, 8 Apr 2025 13:43:09 -0400 Subject: [PATCH 2/2] Fix formatting, NFC --- clang/lib/Lex/PPExpressions.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 6a6762828a20e..48835121b40e9 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -345,8 +345,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Parse the integer literal into Result. if (Literal.GetIntegerValue(Result.Val)) { // Overflow parsing integer literal. - PP.Diag(PeekTok, diag::err_integer_literal_too_large) - << /* Unsigned */ 1; + PP.Diag(PeekTok, diag::err_integer_literal_too_large) << /* Unsigned */ 1; Result.Val.setIsUnsigned(true); } else { // Set the signedness of the result to match whether there was a U suffix _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits