]> granicus.if.org Git - clang/commitdiff
PR26349: correctly check whether a digit sequence is empty in the presence of digit...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 9 Feb 2016 22:34:35 +0000 (22:34 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 9 Feb 2016 22:34:35 +0000 (22:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260307 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/LiteralSupport.h
lib/Lex/LiteralSupport.cpp
test/Lexer/cxx1y_digit_separators.cpp

index dbe9f82374da59eb5187480d5b24a2a47acd36ee..86935d593677cd08a05b6383d764d864ff234738 100644 (file)
@@ -108,6 +108,12 @@ private:
 
   static bool isDigitSeparator(char C) { return C == '\''; }
 
+  /// \brief Determine whether the sequence of characters [Start, End) contains
+  /// any real digits (not digit separators).
+  bool containsDigits(const char *Start, const char *End) {
+    return Start != End && (Start + 1 != End || !isDigitSeparator(Start[0]));
+  }
+
   enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits };
 
   /// \brief Ensure that we don't have a digit separator here.
index fb9d63b940bb58c8c9afa0e123b5c99aea2fb5a4..0c0626c8a85942aada64dd6fde7ac31d3dd9a02b 100644 (file)
@@ -700,7 +700,7 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){
     saw_exponent = true;
     if (*s == '+' || *s == '-')  s++; // sign
     const char *first_non_digit = SkipDigits(s);
-    if (first_non_digit != s) {
+    if (containsDigits(s, first_non_digit)) {
       checkSeparator(TokLoc, s, CSK_BeforeDigits);
       s = first_non_digit;
     } else {
@@ -771,19 +771,21 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
     radix = 16;
     DigitsBegin = s;
     s = SkipHexDigits(s);
-    bool noSignificand = (s == DigitsBegin);
+    bool HasSignificandDigits = containsDigits(DigitsBegin, s);
     if (s == ThisTokEnd) {
       // Done.
     } else if (*s == '.') {
       s++;
       saw_period = true;
       const char *floatDigitsBegin = s;
-      checkSeparator(TokLoc, s, CSK_BeforeDigits);
       s = SkipHexDigits(s);
-      noSignificand &= (floatDigitsBegin == s);
+      if (containsDigits(floatDigitsBegin, s))
+        HasSignificandDigits = true;
+      if (HasSignificandDigits)
+        checkSeparator(TokLoc, floatDigitsBegin, CSK_BeforeDigits);
     }
 
-    if (noSignificand) {
+    if (!HasSignificandDigits) {
       PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin),
         diag::err_hexconstant_requires) << 1;
       hadError = true;
@@ -799,7 +801,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
       saw_exponent = true;
       if (*s == '+' || *s == '-')  s++; // sign
       const char *first_non_digit = SkipDigits(s);
-      if (first_non_digit == s) {
+      if (!containsDigits(s, first_non_digit)) {
         PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
                 diag::err_exponent_has_no_digits);
         hadError = true;
index c4c6aee963da0fb5b6a6a54952c3c2e339756286..c076e7de057289011f73c49171b245ee8649cb5c 100644 (file)
@@ -48,6 +48,9 @@ namespace floating {
   float r = 0.'0e1; // expected-error {{digit separator cannot appear at start of digit sequence}}
   float s = 0.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}
   float t = 0.0e'1; // expected-error {{digit separator cannot appear at start of digit sequence}}
+  float u = 0x.'p1f; // expected-error {{hexadecimal floating constants require a significand}}
+  float v = 0e'f; // expected-error {{exponent has no digits}}
+  float w = 0x0p'f; // expected-error {{exponent has no digits}}
 }
 
 #line 123'456