Commit b9e2d17b by Neil Booth Committed by Neil Booth

cpplex.c (cpp_interpret_charconst): Truncate as well as sign-extend.

	* cpplex.c (cpp_interpret_charconst): Truncate as well as
	sign-extend.
doc:
	* cpp.texi: Clarify multichar charconst valuation.
testsuite:
	* gcc.dg/cpp/charconst-4.c: More tests.

From-SVN: r53301
parent 4434687a
2002-05-08 Neil Booth <neil@daikokuya.demon.co.uk>
* cpplex.c (cpp_interpret_charconst): Truncate as well as
sign-extend.
doc:
* cpp.texi: Clarify multichar charconst valuation.
2002-05-08 Mark Mitchell <mark@codesourcery.com>
* doc/invoke.texi: Document -mwindiss option.
......
......@@ -1954,16 +1954,18 @@ cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
cpp_error (pfile, DL_WARNING, "multi-character character constant");
}
/* Sign-extend the constant. */
if (!unsigned_p)
/* Sign-extend or truncate the constant to cppchar_t. The value is
in WIDTH bits, but for multi-char charconsts it's value is the
full target type's width. */
if (chars_seen > 1)
width *= max_chars;
if (width < BITS_PER_CPPCHAR_T)
{
size_t precision = width;
if (chars_seen > 1)
precision *= max_chars;
if (precision < BITS_PER_CPPCHAR_T
&& (result & ((cppchar_t) 1 << (precision - 1))))
result |= ~(((cppchar_t) 1 << precision) - 1);
mask = ((cppchar_t) 1 << width) - 1;
if (unsigned_p || !(result & (1 << (width - 1))))
result &= mask;
else
result |= ~mask;
}
*pchars_seen = chars_seen;
......
......@@ -3512,19 +3512,21 @@ The preprocessor and compiler interpret character constants in the
same way; i.e.@: escape sequences such as @samp{\a} are given the
values they would have on the target machine.
Multi-character character constants are interpreted a character at a
time, shifting the previous result left by the number of bits per
target character and or-ing the value of the new character truncated
to the width of a target character. They have type @code{int}, and
are treated as signed regardless of whether single characters are
signed or not (a slight change from versions 3.1 and earlier of GCC).
If there are more characters in the constant than would fit in the
target @code{int} an error is issued.
The compiler values a multi-character character constant a character
at a time, shifting the previous value left by the number of bits per
target character, and then or-ing in the bit-pattern of the new
character truncated to the width of a target character. The final
bit-pattern is given type @code{int}, and is therefore signed,
regardless of whether single characters are signed or not (a slight
change from versions 3.1 and earlier of GCC). If there are more
characters in the constant than would fit in the target @code{int} the
compiler issues a warning, and the excess leading characters are
ignored.
For example, 'ab' for a target with an 8-bit @code{char} would be
interpreted as @w{(int) ((unsigned char) 'a' * 256 + (unsigned char)
'b')}, and 'a\234' as @w{(int) ((unsigned char) 'a' * 256 + (unsigned
char) '\234')}.
'b')}, and '\234a' as @w{(int) ((unsigned char) '\234' * 256 + (unsigned
char) 'a')}.
@item Source file inclusion.
......
2002-05-08 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/charconst-4.c: More tests.
2002-05-08 Mark Mitchell <mark@codesourcery.com>
PR c/6569
......
/* Copyright (C) 2001 Free Software Foundation, Inc. */
/* { dg-do run } */
/* { dg-options "-Wno-multichar -fsigned-char" } */
/* This tests how overly-long multichar charconsts are truncated, and
whether "short" multichar charconsts are incorrectly sign extended
(regardless of char signedness). Preprocessor is used so that we
have only one place where the too long warning is generated, so
that the test works for all targets.
Neil Booth, 8 May 2002. */
#include <limits.h>
#if INT_MAX == 32767
# define LONG_CHARCONST '!\234a'
# define SHORT_CHARCONST '\234a'
# define POS_CHARCONST '\1'
#elif INT_MAX == 2147483647
# define LONG_CHARCONST '!\234abc'
# define SHORT_CHARCONST '\234abc'
# define POS_CHARCONST '\234a'
#elif INT_MAX == 9223372036854775807
# define LONG_CHARCONST '!\234abcdefg'
# define SHORT_CHARCONST '\234abcdefg'
# define POS_CHARCONST '\234a'
#else
/* Target int size not handled, do something that won't fail. */
# define LONG_CHARCONST '\234a'
# define SHORT_CHARCONST '\234a'
# define POS_CHARCONST '\1'
#endif
#if POS_CHARCONST < 0
# error Charconst incorrectly sign-extended
#endif
#if LONG_CHARCONST != SHORT_CHARCONST /* { dg-warning "too long" "" } */
# error Overly long charconst truncates wrongly for preprocessor
#endif
int main ()
{
if (POS_CHARCONST < 0)
abort ();
if (LONG_CHARCONST != SHORT_CHARCONST) /* { dg-warning "too long" "" } */
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment