Article View: gnu.gcc.bug
Article #1120gcc-141/222 cpp bug
From: Andreas Arens
Date: Thu, 10 Sep 1992 00:24
Date: Thu, 10 Sep 1992 00:24
121 lines
4197 bytes
4197 bytes
The following is a small patch that fixes two problems I found with
gcc-1.41 cpp. The second one also applies to gcc-2.2.2 cpp.
1. gcc-1.41 cpp (not gcc-2.x) has a problem with '=' in CPP_PREDEFINES.
Including something like "-D__STRICT_NAMES__=1" in the macro works
within gcc.c, but fails within cccp.c, since make_definition expects
a ' ' instead of a '='.
2. The following small input file demonstrates the problem:
-------cut-------
#define XX 0x00
echo XX
echo 0xEEED-XX
echo 0xEEEE-XX
echo 0xEEEF-XX
echo 0xEEED+XX
echo 0xEEEE+XX
echo 0xEEEF+XX
-----------------
In normal mode (not with -traditional) the lines 0xEEEE+|-XX do not
expand the macro XX. This is because ANSI C does not touch floating
point numbers within the preprocessor. The preprocessor has a very
rudimentary routine to detect numbers in such a case. It's only way
to detect a floating point number is an 'e' or 'E' followed by
a digit or '+' or '-'. Of course this can also happen if a macro is
added to or subtracted from a hex number, as shown in the sample above.
The second small patch allways forces the '+' or '-' to end the
token if it contained the character 'x' or 'X' before. This fix can
easily be done to cccc.c in gcc-2.2.2 also.
----- patches follow ------
*** cccp.c Wed Sep 2 18:01:29 1992
--- cccp.new.c Wed Sep 9 21:17:35 1992
***************
*** 833,848 ****
/* Do standard #defines that identify processor type. */
if (!inhibit_predefs) {
char *p = (char *) alloca (strlen (predefs) + 1);
strcpy (p, predefs);
while (*p) {
char *q;
if (p[0] != '-' || p[1] != 'D')
abort ();
q = &p[2];
! while (*p && *p != ' ') p++;
if (*p != 0)
*p++= 0;
make_definition (q);
}
--- 833,856 ----
/* Do standard #defines that identify processor type. */
if (!inhibit_predefs) {
+ int hadeq;
char *p = (char *) alloca (strlen (predefs) + 1);
strcpy (p, predefs);
while (*p) {
char *q;
if (p[0] != '-' || p[1] != 'D')
abort ();
q = &p[2];
! hadeq = 0;
! while (*p && *p != ' ') {
! if (*p == '=' && !hadeq) {
! *p = ' ';
! hadeq = 1;
! }
! p++;
! }
if (*p != 0)
*p++= 0;
make_definition (q);
}
***************
*** 1648,1655 ****
--- 1656,1664 ----
So copy all alphanumerics that follow without accumulating
as an identifier. Periods also, for sake of "3.e7". */
if (ident_length == 0) {
+ int is_an_intnum = 0;
while (ibp < limit) {
while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
++ip->lineno;
ibp += 2;
***************
*** 1657,1669 ****
c = *ibp++;
if (!isalnum (c) && c != '.' && c != '_') {
--ibp;
break;
}
*obp++ = c;
/* A sign can be part of a preprocessing number
if it follows an e. */
! if (c == 'e' || c == 'E') {
while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
++ip->lineno;
ibp += 2;
}
--- 1666,1683 ----
c = *ibp++;
if (!isalnum (c) && c != '.' && c != '_') {
--ibp;
break;
+ } else {
+ /* this will catch 0x... and 0X..., which can also end in 'e' or 'E',
+ but will break the token before '+' and '-' even if not traditional. */
+ if (c == 'x' || c == 'X')
+ is_an_intnum = 1;
}
*obp++ = c;
/* A sign can be part of a preprocessing number
if it follows an e. */
! if (!is_an_intnum && (c == 'e' || c == 'E')) {
while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
++ip->lineno;
ibp += 2;
}
Technical Details
Message-ID:
<27.3826@tron.gun.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!wupost!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!tron.gun.DE!ariShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!wupost!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!tron.gun.DE!ari From: ari@tron.gun.DE (Andreas Arens) Subject: gcc-141/222 cpp bug Message-ID: <27.3826@tron.gun.de> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Thu, 10 Sep 1992 00:24:00 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 122