[cfe-commits] r65401 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/CodeGenObjC/encode-test-3.m

Chris Lattner sabre at nondot.org
Tue Feb 24 15:10:29 PST 2009


Author: lattner
Date: Tue Feb 24 17:10:27 2009
New Revision: 65401

URL: http://llvm.org/viewvc/llvm-project?rev=65401&view=rev
Log:
handle @encode interactions with array initializers.

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/CodeGenObjC/encode-test-3.m

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=65401&r1=65400&r2=65401&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Feb 24 17:10:27 2009
@@ -18,7 +18,7 @@
 #include "Sema.h"
 #include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
 #include <map>
 using namespace clang;
 
@@ -26,11 +26,13 @@
 // Sema Initialization Checking
 //===----------------------------------------------------------------------===//
 
-static StringLiteral *IsStringInit(Expr *Init, QualType DeclType,
-                                   ASTContext &Context) {
+static Expr *IsStringInit(Expr *Init, QualType DeclType, ASTContext &Context) {
   if (const ArrayType *AT = Context.getAsArrayType(DeclType))
-    if (AT->getElementType()->isCharType())
-      return dyn_cast<StringLiteral>(Init->IgnoreParens());
+    if (AT->getElementType()->isCharType()) {
+      Init = Init->IgnoreParens();
+      if (isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init))
+        return Init;
+    }
   return 0;
 }
 
@@ -56,10 +58,13 @@
                                   InitType, Init, "initializing");
 }
 
-static void CheckStringInit(Expr *Str, unsigned StrLength,
-                            QualType &DeclT, Sema &S) {
-  const ArrayType *AT = S.Context.getAsArrayType(DeclT);
+static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) {
+  // Get the length of the string as parsed.
+  uint64_t StrLength =
+    cast<ConstantArrayType>(Str->getType())->getSize().getZExtValue();
+
   
+  const ArrayType *AT = S.Context.getAsArrayType(DeclT);
   if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
     // C99 6.7.8p14. We have an array of character type with unknown size 
     // being initialized to a string literal.
@@ -76,7 +81,7 @@
   // C99 6.7.8p14. We have an array of character type with known size.  However,
   // the size may be smaller or larger than the string we are initializing.
   // FIXME: Avoid truncation for 64-bit length strings.
-  if (StrLength-1 > (unsigned)CAT->getSize().getZExtValue())
+  if (StrLength-1 > CAT->getSize().getZExtValue())
     S.Diag(Str->getSourceRange().getBegin(),
            diag::warn_initializer_string_for_char_array_too_long)
       << Str->getSourceRange();
@@ -111,8 +116,8 @@
   InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
   if (!InitList) {
     // FIXME: Handle wide strings
-    if (StringLiteral *Str = IsStringInit(Init, DeclType, Context)) {
-      CheckStringInit(Str, Str->getByteLength() + 1, DeclType, *this);
+    if (Expr *Str = IsStringInit(Init, DeclType, Context)) {
+      CheckStringInit(Str, DeclType, *this);
       return false;
     }
     
@@ -587,9 +592,8 @@
                           newStructuredList, newStructuredIndex);
     ++StructuredIndex;
     ++Index;
-  } else if (StringLiteral *Str = IsStringInit(expr, ElemType,
-                                               SemaRef.Context)) {
-    CheckStringInit(Str, Str->getByteLength() + 1, ElemType, SemaRef);
+  } else if (Expr *Str = IsStringInit(expr, ElemType, SemaRef.Context)) {
+    CheckStringInit(Str, ElemType, SemaRef);
     UpdateStructuredListElement(StructuredList, StructuredIndex, Str);
     ++Index;
   } else if (ElemType->isScalarType()) {
@@ -773,9 +777,9 @@
                                      unsigned &StructuredIndex) {
   // Check for the special-case of initializing an array with a string.
   if (Index < IList->getNumInits()) {
-    if (StringLiteral *Str = IsStringInit(IList->getInit(Index), DeclType,
-                                          SemaRef.Context)) {
-      CheckStringInit(Str, Str->getByteLength() + 1, DeclType, SemaRef);
+    if (Expr *Str = IsStringInit(IList->getInit(Index), DeclType,
+                                 SemaRef.Context)) {
+      CheckStringInit(Str, DeclType, SemaRef);
       // We place the string literal directly into the resulting
       // initializer list. This is the only place where the structure
       // of the structured initializer list doesn't match exactly,

Modified: cfe/trunk/test/CodeGenObjC/encode-test-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/encode-test-3.m?rev=65401&r1=65400&r2=65401&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenObjC/encode-test-3.m (original)
+++ cfe/trunk/test/CodeGenObjC/encode-test-3.m Tue Feb 24 17:10:27 2009
@@ -13,3 +13,9 @@
 int a[sizeof(@encode(int)) == 2 ? 1 : -1]; // Type is char[2]
 const char *B = @encode(int);
 char (*c)[2] = &@encode(int); // @encode is an lvalue
+
+char d[] = @encode(int);   // infer size.
+char e[1] = @encode(int);  // truncate
+char f[2] = @encode(int);  // fits
+char g[3] = @encode(int);  // zero fill
+





More information about the cfe-commits mailing list