[cfe-commits] r150295 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Lex/LiteralSupport.h lib/Lex/LiteralSupport.cpp test/Lexer/char-literal-encoding-error.c test/Lexer/string-literal-encoding.c

Eli Friedman eli.friedman at gmail.com
Fri Feb 10 21:08:10 PST 2012


Author: efriedma
Date: Fri Feb 10 23:08:10 2012
New Revision: 150295

URL: http://llvm.org/viewvc/llvm-project?rev=150295&view=rev
Log:
Implement warning for non-wide string literals with an unexpected encoding.  Downgrade error for non-wide character literals with an unexpected encoding to a warning for compatibility with gcc and older versions of clang.  <rdar://problem/10837678>.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Lex/LiteralSupport.h
    cfe/trunk/lib/Lex/LiteralSupport.cpp
    cfe/trunk/test/Lexer/char-literal-encoding-error.c
    cfe/trunk/test/Lexer/string-literal-encoding.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=150295&r1=150294&r2=150295&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Feb 10 23:08:10 2012
@@ -136,9 +136,16 @@
   "unsupported non-standard concatenation of string literals">;
 def err_bad_string_encoding : Error<
   "illegal character encoding in string literal">;
+def warn_bad_string_encoding : ExtWarn<
+  "illegal character encoding in string literal">,
+  InGroup<DiagGroup<"invalid-source-encoding">>;
 def err_bad_character_encoding : Error<
   "illegal character encoding in character literal">;
-  
+def warn_bad_character_encoding : ExtWarn<
+  "illegal character encoding in character literal">,
+  InGroup<DiagGroup<"invalid-source-encoding">>;
+
+
 //===----------------------------------------------------------------------===//
 // PTH Diagnostics
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=150295&r1=150294&r2=150295&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/trunk/include/clang/Lex/LiteralSupport.h Fri Feb 10 23:08:10 2012
@@ -199,6 +199,7 @@
 private:
   void init(const Token *StringToks, unsigned NumStringToks);
   bool CopyStringFragment(StringRef Fragment);
+  bool DiagnoseBadString(const Token& Tok);
 };
 
 }  // end namespace clang

Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=150295&r1=150294&r2=150295&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/lib/Lex/LiteralSupport.cpp Fri Feb 10 23:08:10 2012
@@ -822,17 +822,32 @@
         ++begin;
       } while (begin != end && *begin != '\\');
 
-      uint32_t *tmp_begin = buffer_begin;
+      char const *tmp_in_start = start;
+      uint32_t *tmp_out_start = buffer_begin;
       ConversionResult res =
       ConvertUTF8toUTF32(reinterpret_cast<UTF8 const **>(&start),
                          reinterpret_cast<UTF8 const *>(begin),
                          &buffer_begin,buffer_end,strictConversion);
       if (res!=conversionOK) {
-        PP.Diag(Loc, diag::err_bad_character_encoding);
-        HadError = true;
+        // If we see bad encoding for unprefixed character literals, warn and 
+        // simply copy the byte values, for compatibility with gcc and 
+        // older versions of clang.
+        bool NoErrorOnBadEncoding = isAscii();
+        unsigned Msg = diag::err_bad_character_encoding;
+        if (NoErrorOnBadEncoding)
+          Msg = diag::warn_bad_character_encoding;
+        PP.Diag(Loc, Msg);
+        if (NoErrorOnBadEncoding) {
+          start = tmp_in_start;
+          buffer_begin = tmp_out_start;
+          for ( ; start != begin; ++start, ++buffer_begin)
+            *buffer_begin = static_cast<uint8_t>(*start);
+        } else {
+          HadError = true;
+        }
       } else {
-        for (; tmp_begin<buffer_begin; ++tmp_begin) {
-          if (*tmp_begin > largest_character_for_kind) {
+        for (; tmp_out_start <buffer_begin; ++tmp_out_start) {
+          if (*tmp_out_start > largest_character_for_kind) {
             HadError = true;
             PP.Diag(Loc, diag::err_character_too_large);
           }
@@ -1097,10 +1112,8 @@
       // Copy the string over
       if (CopyStringFragment(StringRef(ThisTokBuf,ThisTokEnd-ThisTokBuf)))
       {
-        if (Diags)
-          Diags->Report(FullSourceLoc(StringToks[i].getLocation(), SM),
-                        diag::err_bad_string_encoding);
-        hadError = true;
+        if (DiagnoseBadString(StringToks[i]))
+          hadError = true;
       }
 
     } else {
@@ -1131,10 +1144,8 @@
           // Copy the character span over.
           if (CopyStringFragment(StringRef(InStart,ThisTokBuf-InStart)))
           {
-            if (Diags)
-              Diags->Report(FullSourceLoc(StringToks[i].getLocation(), SM),
-                            diag::err_bad_string_encoding);
-            hadError = true;
+            if (DiagnoseBadString(StringToks[i]))
+              hadError = true;
           }
           continue;
         }
@@ -1219,6 +1230,9 @@
   ConversionResult result = conversionOK;
   // Copy the character span over.
   if (CharByteWidth == 1) {
+    if (!isLegalUTF8Sequence(reinterpret_cast<const UTF8*>(Fragment.begin()),
+                             reinterpret_cast<const UTF8*>(Fragment.end())))
+      result = sourceIllegal;
     memcpy(ResultPtr, Fragment.data(), Fragment.size());
     ResultPtr += Fragment.size();
   } else if (CharByteWidth == 2) {
@@ -1226,7 +1240,7 @@
     // FIXME: Make the type of the result buffer correct instead of
     // using reinterpret_cast.
     UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
-    ConversionFlags flags = lenientConversion;
+    ConversionFlags flags = strictConversion;
     result = ConvertUTF8toUTF16(
 	    &sourceStart,sourceStart + Fragment.size(),
         &targetStart,targetStart + 2*Fragment.size(),flags);
@@ -1237,7 +1251,7 @@
     // FIXME: Make the type of the result buffer correct instead of
     // using reinterpret_cast.
     UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
-    ConversionFlags flags = lenientConversion;
+    ConversionFlags flags = strictConversion;
     result = ConvertUTF8toUTF32(
         &sourceStart,sourceStart + Fragment.size(),
         &targetStart,targetStart + 4*Fragment.size(),flags);
@@ -1249,6 +1263,17 @@
   return result != conversionOK;
 }
 
+bool StringLiteralParser::DiagnoseBadString(const Token &Tok) {
+  // If we see bad encoding for unprefixed string literals, warn and
+  // simply copy the byte values, for compatibility with gcc and older
+  // versions of clang.
+  bool NoErrorOnBadEncoding = isAscii();
+  unsigned Msg = NoErrorOnBadEncoding ? diag::warn_bad_string_encoding :
+                                        diag::err_bad_string_encoding;
+  if (Diags)
+    Diags->Report(FullSourceLoc(Tok.getLocation(), SM), Msg);
+  return !NoErrorOnBadEncoding;
+}
 
 /// getOffsetOfStringByte - This function returns the offset of the
 /// specified byte of the string data represented by Token.  This handles

Modified: cfe/trunk/test/Lexer/char-literal-encoding-error.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/char-literal-encoding-error.c?rev=150295&r1=150294&r2=150295&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/char-literal-encoding-error.c (original)
+++ cfe/trunk/test/Lexer/char-literal-encoding-error.c Fri Feb 10 23:08:10 2012
@@ -3,8 +3,13 @@
 // This file is encoded using ISO-8859-1
 
 int main() {
-  'é'; // expected-error {{illegal character encoding in character literal}}
-  u'é'; // expected-error {{illegal character encoding in character literal}}
-  U'é'; // expected-error {{illegal character encoding in character literal}}
-  L'é'; // expected-error {{illegal character encoding in character literal}}
+  (void)'é'; // expected-warning {{illegal character encoding in character literal}}
+  (void)u'é'; // expected-error {{illegal character encoding in character literal}}
+  (void)U'é'; // expected-error {{illegal character encoding in character literal}}
+  (void)L'é'; // expected-error {{illegal character encoding in character literal}}
+
+  // For narrow character literals, since there is no error, make sure the
+  // encoding is correct
+  static_assert((unsigned char)'é' == 0xE9, ""); // expected-warning {{illegal character encoding in character literal}}
+  static_assert('éé' == 0xE9E9, ""); // expected-warning {{illegal character encoding in character literal}} expected-warning {{multi-character character constant}}
 }

Modified: cfe/trunk/test/Lexer/string-literal-encoding.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/string-literal-encoding.c?rev=150295&r1=150294&r2=150295&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/string-literal-encoding.c (original)
+++ cfe/trunk/test/Lexer/string-literal-encoding.c Fri Feb 10 23:08:10 2012
@@ -12,4 +12,7 @@
     wchar_t const *d = LR"(Àéîõü)"; // expected-error {{illegal character encoding in string literal}}
     char16_t const *e = uR"(Àéîõü)"; // expected-error {{illegal character encoding in string literal}}
     char32_t const *f = UR"(Àéîõü)"; // expected-error {{illegal character encoding in string literal}}
+
+    char const *g = "Àéîõü"; // expected-warning {{illegal character encoding in string literal}}
+    char const *h = u8"Àéîõü"; // expected-error {{illegal character encoding in string literal}}
 }





More information about the cfe-commits mailing list