Jakub Jelinek aa9d3f17ff c++, libcpp: Allow some left shifts in the preprocessor [PR119391]
The libcpp left shift handling implements (partially) the C99-C23
wording where shifts are UB if shift count is negative, or too large,
or shifting left a negative value or shifting left non-negative value
results in something not representable in the result type (in the
preprocessor case that is intmax_t).
libcpp actually implements left shift by negative count as right shifts
by negation of the count and similarly right shifts by negative count
as left shifts by negation (not ok), sets overflow for too large shift
count (ok), doesn't check for negative values on left shift (not ok)
and checks correctly for the non-representable ones otherwise (ok).

Now, C++11 to C++17 has different behavior, whereas in C99-C23 1 << 63
in preprocessor is invalid, in C++11-17 it is valid, but 3 << 63 is
not.  The wording is that left shift of negative value is UB (like in C)
and signed non-negative left shift is UB if the result isn't representable
in corresponding unsigned type (so uintmax_t for libcpp).

And then C++20 and newer says all left shifts are well defined with the
exception of bad shift counts.

In -fsanitize=undefined we handle these by
  /* For signed x << y, in C99 and later, the following:
     (unsigned) x >> (uprecm1 - y)
     if non-zero, is undefined.  */
and
  /* For signed x << y, in C++11 to C++17, the following:
     x < 0 || ((unsigned) x >> (uprecm1 - y))
     if > 1, is undefined.  */

Now, we are late in GCC 15 development, so I think making the preprocessor
more strict than it is now is undesirable, so will defer setting overflow
flag for the shifts by negative count, or shifts by negative value left.

The following patch just makes some previously incorrectly rejected or
warned cases valid for C++11-17 and even more for C++20 and later.

2025-04-04  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/119391
	* expr.cc (num_lshift): Add pfile argument.  Don't set num.overflow
	for !num.unsignedp in C++20 or later unless n >= precision.  For
	C++11 to C++17 set it if orig >> (precision - 1 - n) as logical
	shift results in value > 1.
	(num_binary_op): Pass pfile to num_lshift.
	(num_div_op): Likewise.

	* g++.dg/cpp/pr119391.C: New test.
2025-04-04 17:30:32 +02:00
2025-01-02 11:59:57 +01:00
2024-11-26 00:19:26 +00:00
2025-03-28 00:19:00 +00:00
2024-07-12 00:17:52 +00:00
2025-04-02 00:18:25 +00:00
2024-04-16 00:18:06 +00:00
2025-03-30 00:16:46 +00:00
2025-01-02 11:59:57 +01:00
2025-01-11 00:19:49 +00:00
2025-02-11 00:17:27 +00:00
2025-01-02 11:59:57 +01:00
2025-01-02 11:59:57 +01:00
2024-10-26 00:19:39 +00:00
2025-03-23 00:17:38 +00:00
2025-04-04 00:16:45 +00:00
2025-03-23 00:17:38 +00:00
2025-03-29 00:17:59 +00:00
2025-03-27 00:19:18 +00:00
2025-04-01 00:19:09 +00:00
2025-03-30 00:16:46 +00:00
2025-01-03 00:17:15 +00:00
2025-01-02 11:59:57 +01:00
2025-04-01 00:19:09 +00:00
2025-04-02 00:18:25 +00:00
2025-01-07 00:18:08 +00:00
2025-01-02 11:59:57 +01:00
2025-01-02 11:59:57 +01:00
2025-03-07 00:17:19 +00:00
2025-04-01 00:19:09 +00:00
2025-04-03 00:18:15 +00:00
2025-03-31 23:35:29 +01:00
2024-11-19 12:27:33 +01:00

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.
Description
No description provided
Readme 1.5 GiB
Languages
C++ 30.7%
C 30%
Ada 14.5%
D 6.1%
Go 5.7%
Other 12.5%