summaryrefslogtreecommitdiff
path: root/gcc/cppexp.c
diff options
context:
space:
mode:
authorbrolley <brolley@138bc75d-0d04-0410-961f-82ee72b054a4>1998-12-07 13:35:20 +0000
committerbrolley <brolley@138bc75d-0d04-0410-961f-82ee72b054a4>1998-12-07 13:35:20 +0000
commitbbe5b5e390cbfc384dfeba093af5d0054f7cf3f0 (patch)
tree8639ccd7c1c382473eaf051751bf1a983dde27b5 /gcc/cppexp.c
parentcaa859cdde89b29e003c9a0e9b469dd79effd516 (diff)
downloadgcc-bbe5b5e390cbfc384dfeba093af5d0054f7cf3f0.tar.gz
1998-11-26 01:17 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
* cpplib.h (struct cpp_buffer): Replace dir and dlen members with a struct file_name_list pointer. (struct cpp_reader): Add pointer to chain of `actual directory' include searchpath entries. (struct file_name_list): Add *alloc pointer for the sake of the actual-directory chain. Move definition of HOST_WIDE_INT here. (cpp_parse_escape): Change prototype to match changes in cppexp.c. * cppfiles.c (actual_directory): New function. (finclude): Use it to initialize the buffer's actual_dir entry. (find_include_file): We don't need to fix up max_include_len here. * cpplib.c (do_include): Don't allocate a file_name_list on the fly for current directory "" includes, use the one that's been preallocated in pfile->buffer->actual_dir. Hoist out duplicate code from the search_start selection logic. (cpp_reader_init): Initialize pfile->actual_dirs. Remove definition of HOST_WIDE_INT. Change calls to cpp_parse_escape to match changes in cppexp.c (note hardcoded MASK, which is safe since this is the source character set). * cppexp.c: Bring over changes to cpp_parse_escape from cccp.c to handle wide character constants in #if directives. The function now returns a HOST_WIDE_INT, and takes a third argument which is a binary mask for all legal values (0x00ff for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.) Define MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK. Change callers of cpp_parse_escape to match. [Fixes c-torture/execute/widechar-1.c] git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24153 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cppexp.c')
-rw-r--r--gcc/cppexp.c62
1 files changed, 25 insertions, 37 deletions
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 419e5bd79dc..87b84a624fc 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -72,6 +72,14 @@ struct arglist {
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif
+#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
+ ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+ : ~ (HOST_WIDE_INT) 0)
+
+#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
+ ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
+ : ~ (HOST_WIDE_INT) 0)
+
/* Yield nonzero if adding two numbers with A's and B's signs can yield a
number with SUM's sign, where A, B, and SUM are all C integers. */
#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
@@ -101,28 +109,6 @@ static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long));
#define SKIP_OPERAND 8
/*#define UNSIGNEDP 16*/
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
- && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
- || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
@@ -275,7 +261,7 @@ cpp_lex (pfile, skip_evaluation)
cpp_reader *pfile;
int skip_evaluation;
{
- register int c;
+ register HOST_WIDE_INT c;
register struct token *toktab;
enum cpp_token token;
struct operation op;
@@ -359,7 +345,9 @@ cpp_lex (pfile, skip_evaluation)
{
if (c == '\\')
{
- c = cpp_parse_escape (pfile, (char **) &ptr);
+ c = cpp_parse_escape (pfile, (char **) &ptr,
+ wide_flag ? MAX_WCHAR_TYPE_MASK
+ : MAX_CHAR_TYPE_MASK);
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= (unsigned)(1 << width))
cpp_pedwarn (pfile,
@@ -480,10 +468,11 @@ cpp_lex (pfile, skip_evaluation)
If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */
-int
-cpp_parse_escape (pfile, string_ptr)
+HOST_WIDE_INT
+cpp_parse_escape (pfile, string_ptr, result_mask)
cpp_reader *pfile;
char **string_ptr;
+ HOST_WIDE_INT result_mask;
{
register int c = *(*string_ptr)++;
switch (c)
@@ -494,7 +483,7 @@ cpp_parse_escape (pfile, string_ptr)
return TARGET_BS;
case 'e':
case 'E':
- if (CPP_PEDANTIC (pfile))
+ if (CPP_OPTIONS (pfile)->pedantic)
cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
return 033;
case 'f':
@@ -522,7 +511,7 @@ cpp_parse_escape (pfile, string_ptr)
case '6':
case '7':
{
- register int i = c - '0';
+ register HOST_WIDE_INT i = c - '0';
register int count = 0;
while (++count < 3)
{
@@ -535,17 +524,17 @@ cpp_parse_escape (pfile, string_ptr)
break;
}
}
- if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
+ if (i != (i & result_mask))
{
- i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
- cpp_pedwarn (pfile,
- "octal character constant does not fit in a byte");
+ i &= result_mask;
+ cpp_pedwarn (pfile, "octal escape sequence out of range");
}
return i;
}
case 'x':
{
- register unsigned i = 0, overflow = 0, digits_found = 0, digit;
+ register unsigned HOST_WIDE_INT i = 0, overflow = 0;
+ register int digits_found = 0, digit;
for (;;)
{
c = *(*string_ptr)++;
@@ -566,11 +555,10 @@ cpp_parse_escape (pfile, string_ptr)
}
if (!digits_found)
cpp_error (pfile, "\\x used with no following hex digits");
- if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
+ if (overflow | (i != (i & result_mask)))
{
- i &= (1 << BITS_PER_UNIT) - 1;
- cpp_pedwarn (pfile,
- "hex character constant does not fit in a byte");
+ i &= result_mask;
+ cpp_pedwarn (pfile, "hex escape sequence out of range");
}
return i;
}