]> granicus.if.org Git - clang/commitdiff
Have Sema check for validity of CGString literal
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 7 Sep 2010 19:38:13 +0000 (19:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 7 Sep 2010 19:38:13 +0000 (19:38 +0000)
instead of asserting in IRGen. Fixes radar 8390459.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaChecking.cpp
test/CodeGen/illegal-UTF8.m
test/Sema/builtins.c

index 3bb85fc0f09865713365e039e1a704e9f1d8c98c..e3c9967f9e4a22ab18cf9f9886790e404838e1f8 100644 (file)
@@ -3091,6 +3091,9 @@ def err_cfstring_literal_not_string_constant : Error<
   "CFString literal is not a string constant">;
 def warn_cfstring_literal_contains_nul_character : Warning<
   "CFString literal contains NUL character">;
+def warn_cfstring_truncated : Warning<
+  "input conversion stopped due to an input byte that does not "
+  "belong to the input codeset UTF-8">;
 
 // Statements.
 def err_continue_not_in_loop : Error<
index d125b370a07a8992c04df3bbcfb11174577ed0d6..6a527a229e475990422c2e41711f31c2c0e85e49 100644 (file)
@@ -1498,15 +1498,6 @@ GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map,
                                                &ToPtr, ToPtr + NumBytes,
                                                strictConversion);
 
-  // Check for conversion failure.
-  if (Result != conversionOK) {
-    // FIXME: Have Sema::CheckObjCString() validate the UTF-8 string and remove
-    // this duplicate code.
-    assert(Result == sourceIllegal && "UTF-8 to UTF-16 conversion failed");
-    StringLength = NumBytes;
-    return Map.GetOrCreateValue(String);
-  }
-
   // ConvertUTF8toUTF16 returns the length in ToPtr.
   StringLength = ToPtr - &ToBuf[0];
 
index a0b4b988dbeba4a27cf1ae6ed12eec4d502166e6..7b0941e34b6cf8e237ff30a343235e34a3c3db64 100644 (file)
@@ -32,6 +32,8 @@
 #include "llvm/Support/raw_ostream.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/ConvertUTF.h"
+
 #include <limits>
 using namespace clang;
 using namespace sema;
@@ -581,9 +583,6 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
 
 /// CheckObjCString - Checks that the argument to the builtin
 /// CFString constructor is correct
-/// FIXME: GCC currently emits the following warning:
-/// "warning: input conversion stopped due to an input byte that does not
-///           belong to the input codeset UTF-8"
 /// Note: It might also make sense to do the UTF-16 conversion here (would
 /// simplify the backend).
 bool Sema::CheckObjCString(Expr *Arg) {
@@ -602,7 +601,21 @@ bool Sema::CheckObjCString(Expr *Arg) {
          diag::warn_cfstring_literal_contains_nul_character)
       << Arg->getSourceRange();
   }
-
+  if (Literal->containsNonAsciiOrNull()) {
+    llvm::StringRef String = Literal->getString();
+    unsigned NumBytes = String.size();
+    llvm::SmallVector<UTF16, 128> ToBuf(NumBytes);
+    const UTF8 *FromPtr = (UTF8 *)String.data();
+    UTF16 *ToPtr = &ToBuf[0];
+    
+    ConversionResult Result = ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes,
+                                                 &ToPtr, ToPtr + NumBytes,
+                                                 strictConversion);
+    // Check for conversion failure.
+    if (Result != conversionOK)
+      Diag(Arg->getLocStart(),
+           diag::warn_cfstring_truncated) << Arg->getSourceRange();
+  }
   return false;
 }
 
index 871e6e5956a8575d4114374c95774b894eb83ddd..4762e800259f3f0c3f45cde30854822f3f10c2a6 100644 (file)
@@ -2,7 +2,5 @@
 
 @class NSString;
 
-// FIXME: GCC emits the following warning:
-// CodeGen/illegal-UTF8.m:4: warning: input conversion stopped due to an input byte that does not belong to the input codeset UTF-8
 
-NSString *S = @"\xff\xff___WAIT___";
+NSString *S = @"\xff\xff___WAIT___"; // expected-warning {{input conversion stopped due to an input byte that does not belong to the input codeset UTF-8}}
index 787630c1a8c4eaa0de44aada37e6219514817861..21a1f72e1d5f9cde08def9a8a428bad0dd3d58c1 100644 (file)
@@ -26,7 +26,7 @@ int test6(float a, long double b) {
 #define CFSTR __builtin___CFStringMakeConstantString
 void test7() {
   const void *X;
-  X = CFSTR("\242");
+  X = CFSTR("\242"); // expected-warning {{input conversion stopped}}
   X = CFSTR("\0"); // expected-warning {{ CFString literal contains NUL character }}
   X = CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible integer to pointer conversion}}
   X = CFSTR("foo", "bar"); // expected-error {{too many arguments to function call}}