]> granicus.if.org Git - clang/commitdiff
more fun with line markers: the digit string is required to be interpreted
authorChris Lattner <sabre@nondot.org>
Sat, 18 Apr 2009 18:35:15 +0000 (18:35 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 18 Apr 2009 18:35:15 +0000 (18:35 +0000)
as decimal, even if it starts with 0.  Also, since things like 0x1 are
completely illegal, don't even bother using numericliteralparser for them.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69454 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticLexKinds.td
lib/Lex/PPDirectives.cpp
test/Preprocessor/line-directive.c

index 564608865e62bb96891afd324b47118295afdc7b..e1e903fad06a96326b6411cfc8b482eb4bb5f4f0 100644 (file)
@@ -228,8 +228,8 @@ def err_pp_line_requires_integer : Error<
 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">;
index 3d312748f9569a980c6062a2dae1bb436f19ef48..e0bd5a1ee0732925ac33927435a10267728f40b3 100644 (file)
@@ -624,24 +624,27 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
   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) {
@@ -650,12 +653,9 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
     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;
 }
 
@@ -671,7 +671,7 @@ void Preprocessor::HandleLineDirective(Token &Tok) {
 
   // 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
index 98f92f130c65719847906933a45f8ec1614b8d17..04c69a6791adcc19bf3fe29e4dbef647266dfce8 100644 (file)
@@ -4,6 +4,7 @@
 
 #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}}
@@ -69,7 +70,12 @@ typedef int w;  // expected-error {{redefinition of typedef 'w' is invalid in C}
 #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];
+