[cfe-commits] r69454 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td lib/Lex/PPDirectives.cpp test/Preprocessor/line-directive.c

Chris Lattner sabre at nondot.org
Sat Apr 18 11:35:17 PDT 2009


Author: lattner
Date: Sat Apr 18 13:35:15 2009
New Revision: 69454

URL: http://llvm.org/viewvc/llvm-project?rev=69454&view=rev
Log:
more fun with line markers: the digit string is required to be interpreted
as decimal, even if it starts with 0.  Also, since things like 0x1 are
completely illegal, don't even bother using numericliteralparser for them.


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

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=69454&r1=69453&r2=69454&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Sat Apr 18 13:35:15 2009
@@ -228,8 +228,8 @@
 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">;

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=69454&r1=69453&r2=69454&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Sat Apr 18 13:35:15 2009
@@ -624,24 +624,27 @@
   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 @@
     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 @@
 
   // 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

Modified: cfe/trunk/test/Preprocessor/line-directive.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/line-directive.c?rev=69454&r1=69453&r2=69454&view=diff

==============================================================================
--- cfe/trunk/test/Preprocessor/line-directive.c (original)
+++ cfe/trunk/test/Preprocessor/line-directive.c Sat Apr 18 13:35:15 2009
@@ -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 @@
 #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];
+





More information about the cfe-commits mailing list