def err_pp_line_invalid_filename : Error<
"invalid filename for #line directive">;
def warn_pp_line_decimal : Warning<
- "#line directive requires decimal line number">;
-def warn_pp_line_digit_sequence : Warning<
+ "#line directive interprets number as decimal, not octal">;
+def err_pp_line_digit_sequence : Error<
"#line directive requires a simple digit sequence">;
def err_pp_linemarker_requires_integer : Error<
"line marker directive requires a positive integer argument">;
IntegerBuffer.resize(DigitTok.getLength());
const char *DigitTokBegin = &IntegerBuffer[0];
unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin);
- NumericLiteralParser Literal(DigitTokBegin, DigitTokBegin+ActualLength,
- DigitTok.getLocation(), PP);
- if (Literal.hadError)
- return true; // Error already emitted.
- if (Literal.isFloatingLiteral() || Literal.isImaginary) {
- PP.Diag(DigitTok, DiagID);
- return true;
- }
-
- // Parse the integer literal into Result.
- llvm::APInt APVal(32, 0);
- if (Literal.GetIntegerValue(APVal)) {
- // Overflow parsing integer literal.
- PP.Diag(DigitTok, DiagID);
- return true;
+ // Verify that we have a simple digit-sequence, and compute the value. This
+ // is always a simple digit string computed in decimal, so we do this manually
+ // here.
+ Val = 0;
+ for (unsigned i = 0; i != ActualLength; ++i) {
+ if (!isdigit(DigitTokBegin[i])) {
+ PP.Diag(PP.AdvanceToTokenCharacter(DigitTok.getLocation(), i),
+ diag::err_pp_line_digit_sequence);
+ PP.DiscardUntilEndOfDirective();
+ return true;
+ }
+
+ unsigned NextVal = Val*10+(DigitTokBegin[i]-'0');
+ if (NextVal < Val) { // overflow.
+ PP.Diag(DigitTok, DiagID);
+ PP.DiscardUntilEndOfDirective();
+ return true;
+ }
+ Val = NextVal;
}
- Val = APVal.getZExtValue();
// Reject 0, this is needed both by #line numbers and flags.
if (Val == 0) {
return true;
}
- // Warn about hex and octal line numbers. Do this after the check for 0,
- // because it is octal.
- if (Literal.getRadix() != 10)
- PP.Diag(DigitTok, diag::warn_pp_line_decimal);
- else if (Literal.hasSuffix())
- PP.Diag(DigitTok, diag::warn_pp_line_digit_sequence);
+ if (DigitTokBegin[0] == '0')
+ PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal);
+
return false;
}
// Validate the number and convert it to an unsigned.
unsigned LineNo;
- if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer, *this))
+ if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*this))
return;
// Enforce C99 6.10.4p3: "The digit sequence shall not specify ... a
#line 'a' // expected-error {{#line directive requires a positive integer argument}}
#line 0 // expected-error {{#line directive requires a positive integer argument}}
+#line 00 // expected-error {{#line directive requires a positive integer argument}}
#line 2147483648 // expected-warning {{C requires #line number to be less than 2147483648, allowed as extension}}
#line 42 // ok
#line 42 'a' // expected-error {{invalid filename for #line directive}}
#line 2 "foo.c" NONEMPTY( ) // expected-warning{{extra tokens at end of #line directive}}
// PR3940
-#line 0xf // expected-warning {{#line directive requires decimal line number}}
-#line 42U // expected-warning {{#line directive requires a simple digit sequence}}
+#line 0xf // expected-error {{#line directive requires a simple digit sequence}}
+#line 42U // expected-error {{#line directive requires a simple digit sequence}}
+// Line markers are digit strings interpreted as decimal numbers, this is
+// 10, not 8.
+#line 010 // expected-warning {{#line directive interprets number as decimal, not octal}}
+extern int array[__LINE__ == 10 ? 1:-1];
+