You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
static void check_promotion (cpp_reader *, const struct op *);
/* Token type abuse to create unary plus and minus operators. */
-#define CPP_UPLUS (CPP_LAST_CPP_OP + 1)
-#define CPP_UMINUS (CPP_LAST_CPP_OP + 2)
+#define CPP_UPLUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 1))
+#define CPP_UMINUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 2))
/* With -O2, gcc appears to produce nice code, moving the error
message load and subsequent jump completely out of the main path. */
static unsigned int
interpret_float_suffix (const uchar *s, size_t len)
{
- size_t f = 0, l = 0, i = 0;
+ size_t f = 0, l = 0, i = 0, d = 0;
while (len--)
switch (s[len])
case 'l': case 'L': l++; break;
case 'i': case 'I':
case 'j': case 'J': i++; break;
+ case 'd': case 'D':
+ /* Disallow fd, ld suffixes. */
+ if (d && (f || l))
+ return 0;
+ d++;
+ break;
default:
return 0;
}
if (f + l > 1 || i > 1)
return 0;
+ /* Allow dd, df, dl suffixes for decimal float constants. */
+ if (d && ((d + f + l != 2) || i))
+ return 0;
+
return ((i ? CPP_N_IMAGINARY : 0)
| (f ? CPP_N_SMALL :
- l ? CPP_N_LARGE : CPP_N_MEDIUM));
+ l ? CPP_N_LARGE : CPP_N_MEDIUM)
+ | (d ? CPP_N_DFLOAT : 0));
}
/* Subroutine of cpp_classify_number. S points to an integer suffix
"traditional C rejects the \"%.*s\" suffix",
(int) (limit - str), str);
+ /* Radix must be 10 for decimal floats. */
+ if ((result & CPP_N_DFLOAT) && radix != 10)
+ {
+ cpp_error (pfile, CPP_DL_ERROR,
+ "invalid suffix \"%.*s\" with hexadecimal floating constant",
+ (int) (limit - str), str);
+ return CPP_N_INVALID;
+ }
+
result |= CPP_N_FLOATING;
}
else
/* Operator to priority map. Must be in the same order as the first
N entries of enum cpp_ttype. */
-static const struct operator
+static const struct cpp_operator
{
uchar prio;
uchar flags;
/* RSHIFT */ {13, LEFT_ASSOC},
/* LSHIFT */ {13, LEFT_ASSOC},
- /* MIN */ {10, LEFT_ASSOC | CHECK_PROMOTION},
- /* MAX */ {10, LEFT_ASSOC | CHECK_PROMOTION},
-
/* COMPL */ {16, NO_L_OPERAND},
/* AND_AND */ {6, LEFT_ASSOC},
/* OR_OR */ {5, LEFT_ASSOC},
}
else if (want_value)
{
- /* Ordering here is subtle and intended to favor the
- missing parenthesis diagnostics over alternatives. */
- if (op.op == CPP_CLOSE_PAREN)
- {
- if (top->op == CPP_OPEN_PAREN)
- SYNTAX_ERROR ("void expression between '(' and ')'");
- }
- else if (top->op == CPP_EOF)
- SYNTAX_ERROR ("#if with no expression");
- if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
- SYNTAX_ERROR2 ("operator '%s' has no right operand",
- cpp_token_as_text (pfile, top->token));
+ /* We want a number (or expression) and haven't got one.
+ Try to emit a specific diagnostic. */
+ if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
+ SYNTAX_ERROR ("missing expression between '(' and ')'");
+
+ if (op.op == CPP_EOF && top->op == CPP_EOF)
+ SYNTAX_ERROR ("#if with no expression");
+
+ if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
+ SYNTAX_ERROR2 ("operator '%s' has no right operand",
+ cpp_token_as_text (pfile, top->token));
+ else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
+ /* Complain about missing paren during reduction. */;
+ else
+ SYNTAX_ERROR2 ("operator '%s' has no left operand",
+ cpp_token_as_text (pfile, op.token));
}
top = reduce (pfile, top, op.op);
case CPP_MINUS:
case CPP_RSHIFT:
case CPP_LSHIFT:
- case CPP_MIN:
- case CPP_MAX:
case CPP_COMMA:
top[-1].value = num_binary_op (pfile, top[-1].value,
top->value, top->op);
size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
size_t new_size = old_size * 2 + 20;
- pfile->op_stack = xrealloc (pfile->op_stack, new_size * sizeof (struct op));
+ pfile->op_stack = XRESIZEVEC (struct op, pfile->op_stack, new_size);
pfile->op_limit = pfile->op_stack + new_size;
return pfile->op_stack + old_size;
{
cpp_num result;
size_t precision = CPP_OPTION (pfile, precision);
- bool gte;
size_t n;
switch (op)
lhs = num_rshift (lhs, precision, n);
break;
- /* Min / Max. */
- case CPP_MIN:
- case CPP_MAX:
- {
- bool unsignedp = lhs.unsignedp || rhs.unsignedp;
-
- gte = num_greater_eq (lhs, rhs, precision);
- if (op == CPP_MIN)
- gte = !gte;
- if (!gte)
- lhs = rhs;
- lhs.unsignedp = unsignedp;
- }
- break;
-
/* Arithmetic. */
case CPP_MINUS:
rhs = num_negate (rhs, precision);