<div dir="ltr">Does it still fail if you revert this change:<div><br></div><div><div>@@ -736,7 +756,7 @@ void NumericLiteralParser::ParseNumberSt</div><div>   }</div><div><br></div><div>   // Handle simple binary numbers 0b01010</div>
<div>-  if (*s == 'b' || *s == 'B') {</div><div>+  if ((*s == 'b' || *s == 'B') && (s[1] == '0' || s[1] == '1')) {</div></div><div><br></div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Thu, Sep 26, 2013 at 5:14 PM, NAKAMURA Takumi <span dir="ltr"><<a href="mailto:geek4civic@gmail.com" target="_blank">geek4civic@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It might be a bug in msc16. I am investigating.<br>
<br>
2013/9/27 Jordan Rose <<a href="mailto:jordan_rose@apple.com">jordan_rose@apple.com</a>>:<br>
<div class="HOEnZb"><div class="h5">> Looks like this is still causing problems on Takumi's MSC bot. Can you take a look?<br>
><br>
> <a href="http://bb.pgr.jp/builders/cmake-clang-x64-msc16-R/builds/3067" target="_blank">http://bb.pgr.jp/builders/cmake-clang-x64-msc16-R/builds/3067</a><br>
><br>
><br>
> On Sep 25, 2013, at 20:33 , Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
><br>
>> Author: rsmith<br>
>> Date: Wed Sep 25 22:33:06 2013<br>
>> New Revision: 191417<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191417&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=191417&view=rev</a><br>
>> Log:<br>
>> Implement C++1y digit separator proposal (' as a digit separator). This is not<br>
>> yet approved by full committee, but was unanimously supported by EWG.<br>
>><br>
>> Added:<br>
>>    cfe/trunk/test/Lexer/cxx1y_digit_separators.cpp<br>
>> Modified:<br>
>>    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td<br>
>>    cfe/trunk/include/clang/Lex/LiteralSupport.h<br>
>>    cfe/trunk/lib/Lex/Lexer.cpp<br>
>>    cfe/trunk/lib/Lex/LiteralSupport.cpp<br>
>>    cfe/trunk/test/Lexer/cxx1y_binary_literal.cpp<br>
>>    cfe/trunk/test/SemaCXX/cxx98-compat.cpp<br>
>><br>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=191417&r1=191416&r2=191417&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=191417&r1=191416&r2=191417&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)<br>
>> +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Wed Sep 25 22:33:06 2013<br>
>> @@ -159,6 +159,11 @@ def err_invalid_suffix_integer_constant<br>
>>   "invalid suffix '%0' on integer constant">;<br>
>> def err_invalid_suffix_float_constant : Error<<br>
>>   "invalid suffix '%0' on floating constant">;<br>
>> +def warn_cxx11_compat_digit_separator : Warning<<br>
>> +  "digit separators are incompatible with C++ standards before C++1y">,<br>
>> +  InGroup<CXXPre1yCompat>, DefaultIgnore;<br>
>> +def err_digit_separator_not_between_digits : Error<<br>
>> +  "digit separator cannot appear at %select{start|end}0 of digit sequence">;<br>
>> def warn_extraneous_char_constant : Warning<<br>
>>   "extraneous characters in character constant ignored">;<br>
>> def warn_char_constant_too_large : Warning<<br>
>><br>
>> Modified: cfe/trunk/include/clang/Lex/LiteralSupport.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=191417&r1=191416&r2=191417&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=191417&r1=191416&r2=191417&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/Lex/LiteralSupport.h (original)<br>
>> +++ cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Sep 25 22:33:06 2013<br>
>> @@ -100,10 +100,16 @@ private:<br>
>><br>
>>   void ParseNumberStartingWithZero(SourceLocation TokLoc);<br>
>><br>
>> +  static bool isDigitSeparator(char C) { return C == '\''; }<br>
>> +<br>
>> +  /// \brief Ensure that we don't have a digit separator here.<br>
>> +  void checkSeparator(SourceLocation TokLoc, const char *Pos,<br>
>> +                      bool IsAfterDigits);<br>
>> +<br>
>>   /// SkipHexDigits - Read and skip over any hex digits, up to End.<br>
>>   /// Return a pointer to the first non-hex digit or End.<br>
>>   const char *SkipHexDigits(const char *ptr) {<br>
>> -    while (ptr != ThisTokEnd && isHexDigit(*ptr))<br>
>> +    while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr)))<br>
>>       ptr++;<br>
>>     return ptr;<br>
>>   }<br>
>> @@ -111,7 +117,8 @@ private:<br>
>>   /// SkipOctalDigits - Read and skip over any octal digits, up to End.<br>
>>   /// Return a pointer to the first non-hex digit or End.<br>
>>   const char *SkipOctalDigits(const char *ptr) {<br>
>> -    while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7')))<br>
>> +    while (ptr != ThisTokEnd &&<br>
>> +           ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr)))<br>
>>       ptr++;<br>
>>     return ptr;<br>
>>   }<br>
>> @@ -119,7 +126,7 @@ private:<br>
>>   /// SkipDigits - Read and skip over any digits, up to End.<br>
>>   /// Return a pointer to the first non-hex digit or End.<br>
>>   const char *SkipDigits(const char *ptr) {<br>
>> -    while (ptr != ThisTokEnd && isDigit(*ptr))<br>
>> +    while (ptr != ThisTokEnd && (isDigit(*ptr) || isDigitSeparator(*ptr)))<br>
>>       ptr++;<br>
>>     return ptr;<br>
>>   }<br>
>> @@ -127,7 +134,8 @@ private:<br>
>>   /// SkipBinaryDigits - Read and skip over any binary digits, up to End.<br>
>>   /// Return a pointer to the first non-binary digit or End.<br>
>>   const char *SkipBinaryDigits(const char *ptr) {<br>
>> -    while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1'))<br>
>> +    while (ptr != ThisTokEnd &&<br>
>> +           (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr)))<br>
>>       ptr++;<br>
>>     return ptr;<br>
>>   }<br>
>><br>
>> Modified: cfe/trunk/lib/Lex/Lexer.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=191417&r1=191416&r2=191417&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=191417&r1=191416&r2=191417&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Lex/Lexer.cpp (original)<br>
>> +++ cfe/trunk/lib/Lex/Lexer.cpp Wed Sep 25 22:33:06 2013<br>
>> @@ -1606,6 +1606,18 @@ bool Lexer::LexNumericConstant(Token &Re<br>
>>       return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));<br>
>>   }<br>
>><br>
>> +  // If we have a digit separator, continue.<br>
>> +  if (C == '\'' && getLangOpts().CPlusPlus1y) {<br>
>> +    unsigned NextSize;<br>
>> +    char Next = getCharAndSizeNoWarn(CurPtr + Size, NextSize, getLangOpts());<br>
>> +    if (isAlphanumeric(Next)) {<br>
>> +      if (!isLexingRawMode())<br>
>> +        Diag(CurPtr, diag::warn_cxx11_compat_digit_separator);<br>
>> +      CurPtr = ConsumeChar(CurPtr, Size, Result);<br>
>> +      return LexNumericConstant(Result, CurPtr);<br>
>> +    }<br>
>> +  }<br>
>> +<br>
>>   // Update the location of token as well as BufferPtr.<br>
>>   const char *TokStart = BufferPtr;<br>
>>   FormTokenWithChars(Result, CurPtr, tok::numeric_constant);<br>
>><br>
>> Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=191417&r1=191416&r2=191417&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=191417&r1=191416&r2=191417&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)<br>
>> +++ cfe/trunk/lib/Lex/LiteralSupport.cpp Wed Sep 25 22:33:06 2013<br>
>> @@ -498,15 +498,19 @@ NumericLiteralParser::NumericLiteralPars<br>
>>       hadError = true;<br>
>>       return;<br>
>>     } else if (*s == '.') {<br>
>> +      checkSeparator(TokLoc, s, true);<br>
>>       s++;<br>
>>       saw_period = true;<br>
>> +      checkSeparator(TokLoc, s, false);<br>
>>       s = SkipDigits(s);<br>
>>     }<br>
>>     if ((*s == 'e' || *s == 'E')) { // exponent<br>
>> +      checkSeparator(TokLoc, s, true);<br>
>>       const char *Exponent = s;<br>
>>       s++;<br>
>>       saw_exponent = true;<br>
>>       if (*s == '+' || *s == '-')  s++; // sign<br>
>> +      checkSeparator(TokLoc, s, false);<br>
>>       const char *first_non_digit = SkipDigits(s);<br>
>>       if (first_non_digit != s) {<br>
>>         s = first_non_digit;<br>
>> @@ -520,6 +524,7 @@ NumericLiteralParser::NumericLiteralPars<br>
>>   }<br>
>><br>
>>   SuffixBegin = s;<br>
>> +  checkSeparator(TokLoc, s, true);<br>
>><br>
>>   // Parse the suffix.  At this point we can classify whether we have an FP or<br>
>>   // integer constant.<br>
>> @@ -676,6 +681,21 @@ bool NumericLiteralParser::isValidUDSuff<br>
>>       .Default(false);<br>
>> }<br>
>><br>
>> +void NumericLiteralParser::checkSeparator(SourceLocation TokLoc,<br>
>> +                                          const char *Pos, bool IsAfterDigits) {<br>
>> +  if (IsAfterDigits) {<br>
>> +    assert(Pos != ThisTokBegin);<br>
>> +    --Pos;<br>
>> +  } else {<br>
>> +    assert(Pos != ThisTokEnd);<br>
>> +  }<br>
>> +<br>
>> +  if (isDigitSeparator(*Pos))<br>
>> +    PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin),<br>
>> +            diag::err_digit_separator_not_between_digits)<br>
>> +      << IsAfterDigits;<br>
>> +}<br>
>> +<br>
>> /// ParseNumberStartingWithZero - This method is called when the first character<br>
>> /// of the number is found to be a zero.  This means it is either an octal<br>
>> /// number (like '04') or a hex number ('0x123a') a binary number ('0b1010') or<br>
>> @@ -736,7 +756,7 @@ void NumericLiteralParser::ParseNumberSt<br>
>>   }<br>
>><br>
>>   // Handle simple binary numbers 0b01010<br>
>> -  if (*s == 'b' || *s == 'B') {<br>
>> +  if ((*s == 'b' || *s == 'B') && (s[1] == '0' || s[1] == '1')) {<br>
>>     // 0b101010 is a C++1y / GCC extension.<br>
>>     PP.Diag(TokLoc,<br>
>>             PP.getLangOpts().CPlusPlus1y<br>
>> @@ -840,7 +860,8 @@ bool NumericLiteralParser::GetIntegerVal<br>
>>   if (alwaysFitsInto64Bits(radix, NumDigits)) {<br>
>>     uint64_t N = 0;<br>
>>     for (const char *Ptr = DigitsBegin; Ptr != SuffixBegin; ++Ptr)<br>
>> -      N = N * radix + llvm::hexDigitValue(*Ptr);<br>
>> +      if (!isDigitSeparator(*Ptr))<br>
>> +        N = N * radix + llvm::hexDigitValue(*Ptr);<br>
>><br>
>>     // This will truncate the value to Val's input width. Simply check<br>
>>     // for overflow by comparing.<br>
>> @@ -857,6 +878,11 @@ bool NumericLiteralParser::GetIntegerVal<br>
>><br>
>>   bool OverflowOccurred = false;<br>
>>   while (Ptr < SuffixBegin) {<br>
>> +    if (isDigitSeparator(*Ptr)) {<br>
>> +      ++Ptr;<br>
>> +      continue;<br>
>> +    }<br>
>> +<br>
>>     unsigned C = llvm::hexDigitValue(*Ptr++);<br>
>><br>
>>     // If this letter is out of bound for this radix, reject it.<br>
>> @@ -885,8 +911,17 @@ NumericLiteralParser::GetFloatValue(llvm<br>
>>   using llvm::APFloat;<br>
>><br>
>>   unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin);<br>
>> -  return Result.convertFromString(StringRef(ThisTokBegin, n),<br>
>> -                                  APFloat::rmNearestTiesToEven);<br>
>> +<br>
>> +  llvm::SmallString<16> Buffer;<br>
>> +  StringRef Str(ThisTokBegin, n);<br>
>> +  if (Str.find('\'') != StringRef::npos) {<br>
>> +    Buffer.reserve(n);<br>
>> +    std::remove_copy_if(Str.begin(), Str.end(), std::back_inserter(Buffer),<br>
>> +                        &isDigitSeparator);<br>
>> +    Str = Buffer;<br>
>> +  }<br>
>> +<br>
>> +  return Result.convertFromString(Str, APFloat::rmNearestTiesToEven);<br>
>> }<br>
>><br>
>><br>
>><br>
>> Modified: cfe/trunk/test/Lexer/cxx1y_binary_literal.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx1y_binary_literal.cpp?rev=191417&r1=191416&r2=191417&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx1y_binary_literal.cpp?rev=191417&r1=191416&r2=191417&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/Lexer/cxx1y_binary_literal.cpp (original)<br>
>> +++ cfe/trunk/test/Lexer/cxx1y_binary_literal.cpp Wed Sep 25 22:33:06 2013<br>
>> @@ -17,3 +17,4 @@ int k1 = 0b1234; // expected-error {{inv<br>
>> // we'll need to rework our binary literal parsing rules.<br>
>> int k2 = 0b10010f; // expected-error {{invalid digit 'f' in binary constant}}<br>
>> int k3 = 0b10010g; // expected-error {{invalid suffix 'g' on integer constant}}<br>
>> +int k4 = 0b; // expected-error {{invalid digit 'b' in octal constant}}<br>
>><br>
>> Added: cfe/trunk/test/Lexer/cxx1y_digit_separators.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx1y_digit_separators.cpp?rev=191417&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx1y_digit_separators.cpp?rev=191417&view=auto</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/Lexer/cxx1y_digit_separators.cpp (added)<br>
>> +++ cfe/trunk/test/Lexer/cxx1y_digit_separators.cpp Wed Sep 25 22:33:06 2013<br>
>> @@ -0,0 +1,34 @@<br>
>> +// RUN: %clang_cc1 -std=c++1y -verify %s<br>
>> +<br>
>> +int operator""ms(unsigned long long); // expected-warning {{reserved}}<br>
>> +float operator""ms(long double); // expected-warning {{reserved}}<br>
>> +<br>
>> +namespace integral {<br>
>> +  static_assert(1'2'3 == 12'3, "");<br>
>> +  static_assert(1'000'000 == 0xf'4240, "");<br>
>> +  static_assert(0'004'000'000 == 0x10'0000, "");<br>
>> +  static_assert(0b0101'0100 == 0x54, "");<br>
>> +<br>
>> +  int a = 123'; //'; // expected-error {{expected ';'}}<br>
>> +  int b = 0'xff; // expected-error {{digit separator cannot appear at end of digit sequence}} expected-error {{suffix 'xff' on integer}}<br>
>> +  int c = 0x'ff; // expected-error {{suffix 'x'ff' on integer}}<br>
>> +  int d = 0'1234; // ok, octal<br>
>> +  int e = 0'b1010; // expected-error {{digit 'b' in octal constant}}<br>
>> +  int f = 0b'1010; // expected-error {{invalid digit 'b' in octal}}<br>
>> +  int g = 123'ms; // expected-error {{digit separator cannot appear at end of digit sequence}}<br>
>> +<br>
>> +  // FIXME: not yet known if _ after ' will be permitted.<br>
>> +  int z = 0'123'_foo; //'; // expected-error {{expected ';'}}<br>
>> +}<br>
>> +<br>
>> +namespace floating {<br>
>> +  static_assert(0'123.456'7 == 123.4567, "");<br>
>> +  static_assert(1e1'0 == 10'000'000'000, "");<br>
>> +<br>
>> +  float a = 1'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}<br>
>> +  float b = 1'0e1;<br>
>> +  float c = 1.'0e1; // expected-error {{digit separator cannot appear at start of digit sequence}}<br>
>> +  float d = 1.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}<br>
>> +  float e = 1e'1; // expected-error {{digit separator cannot appear at start of digit sequence}}<br>
>> +  float f = 1e1'ms; // expected-error {{digit separator cannot appear at end of digit sequence}}<br>
>> +}<br>
>><br>
>> Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=191417&r1=191416&r2=191417&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=191417&r1=191416&r2=191417&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)<br>
>> +++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Wed Sep 25 22:33:06 2013<br>
>> @@ -1,8 +1,5 @@<br>
>> // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s<br>
>> -// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s<br>
>> -// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-c++11-compat -verify %s -DCXX1YCOMPAT<br>
>> -<br>
>> -#ifndef CXX1YCOMPAT<br>
>> +// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-compat -verify %s -DCXX1YCOMPAT<br>
>><br>
>> namespace std {<br>
>>   struct type_info;<br>
>> @@ -381,7 +378,6 @@ namespace rdar11736429 {<br>
>>     X x; // expected-warning{{union member 'x' with a non-trivial constructor is incompatible with C++98}}<br>
>>   };<br>
>> }<br>
>> -#endif<br>
>><br>
>> template<typename T> T var = T(10);<br>
>> #ifdef CXX1YCOMPAT<br>
>> @@ -455,3 +451,6 @@ template<> int B::v<int> = 10;<br>
>> template int B::v<int>;<br>
>> float fsvar = B::v<float>;<br>
>><br>
>> +#ifdef CXX1YCOMPAT<br>
>> +int digit_seps = 123'456; // expected-warning {{digit separators are incompatible with C++ standards before C++1y}}<br>
>> +#endif<br>
>><br>
>><br>
>> _______________________________________________<br>
>> cfe-commits mailing list<br>
>> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
><br>
</div></div></blockquote></div><br></div>