]> granicus.if.org Git - clang/commitdiff
allow wide strings to initialize arrays compatible with wchar_t.
authorChris Lattner <sabre@nondot.org>
Thu, 26 Feb 2009 23:26:43 +0000 (23:26 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 26 Feb 2009 23:26:43 +0000 (23:26 +0000)
Unfortunately this doesn't work yet because wchar_t is completely
broken in C.

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

lib/Sema/SemaInit.cpp

index f4c375dfff16fd4f36cb71cd9806c2839e8a020a..eeda1d05ca3940e130ba2e782bfed64b8acf931f 100644 (file)
@@ -27,12 +27,31 @@ using namespace clang;
 //===----------------------------------------------------------------------===//
 
 static Expr *IsStringInit(Expr *Init, QualType DeclType, ASTContext &Context) {
-  if (const ArrayType *AT = Context.getAsArrayType(DeclType))
-    if (AT->getElementType()->isCharType()) {
-      Init = Init->IgnoreParens();
-      if (isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init))
-        return Init;
-    }
+  const ArrayType *AT = Context.getAsArrayType(DeclType);
+  if (!AT) return 0;
+
+  // See if this is a string literal or @encode.
+  Init = Init->IgnoreParens();
+  
+  // Handle @encode, which is a narrow string.
+  if (isa<ObjCEncodeExpr>(Init) && AT->getElementType()->isCharType())
+    return Init;
+
+  // Otherwise we can only handle string literals.
+  StringLiteral *SL = dyn_cast<StringLiteral>(Init);
+  
+  // char array can be initialized with a narrow string.
+  // Only allow char x[] = "foo";  not char x[] = L"foo";
+  if (!SL->isWide())
+    return AT->getElementType()->isCharType() ? Init : 0;
+
+  // wchar_t array can be initialized with a wide string: C99 6.7.8p15:
+  // "An array with element type compatible with wchar_t may be initialized by a
+  // wide string literal, optionally enclosed in braces."
+  if (Context.typesAreCompatible(Context.WCharTy, AT->getElementType()))
+    // Only allow wchar_t x[] = L"foo";  not wchar_t x[] = "foo";
+    return Init;
+  
   return 0;
 }