<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">My last commit seems to have broken the "CodeGen/globalinit.c" test.<div><br class="webkit-block-placeholder"></div><div>I thought the appropriate casts were being done. Apparently not.</div><div><br class="webkit-block-placeholder"></div><div>I will investigate,</div><div><br class="webkit-block-placeholder"></div><div>snaroff<br><div><br><div>Begin forwarded message:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>From: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica">Steve Naroff <<a href="mailto:snaroff@apple.com">snaroff@apple.com</a>></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>Date: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica">December 10, 2007 2:44:33 PM PST</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>To: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica"><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>Subject: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica"><b>[cfe-commits] r44816 - in /cfe/trunk: Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/Basic/DiagnosticKinds.def test/Sema/array-constraint.c test/Sema/array-init.c</b></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div> </div>Author: snaroff<br>Date: Mon Dec 10 16:44:33 2007<br>New Revision: 44816<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=44816&view=rev">http://llvm.org/viewvc/llvm-project?rev=44816&view=rev</a><br>Log:<br><br>Add support for initializing char arrays from string literals.<br><br>Adapted from a patch by Anders Carlsson.<br><br><br>Modified:<br>    cfe/trunk/Sema/Sema.h<br>    cfe/trunk/Sema/SemaDecl.cpp<br>    cfe/trunk/Sema/SemaExpr.cpp<br>    cfe/trunk/include/clang/Basic/DiagnosticKinds.def<br>    cfe/trunk/test/Sema/array-constraint.c<br>    cfe/trunk/test/Sema/array-init.c<br><br>Modified: cfe/trunk/Sema/Sema.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=44816&r1=44815&r2=44816&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=44816&r1=44815&r2=44816&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/Sema/Sema.h (original)<br>+++ cfe/trunk/Sema/Sema.h Mon Dec 10 16:44:33 2007<br>@@ -684,7 +684,10 @@<br>   void CheckConstantInitList(QualType DeclType, InitListExpr *IList, <br>                              QualType ElementType, bool isStatic, <br>                              int &nInitializers, bool &hadError);<br>-                             <br>+  bool CheckForCharArrayInitializer(InitListExpr *IList, QualType ElementType,<br>+                                    int &nInitializers, bool isConstant,<br>+                                    bool &hadError);<br>+  <br>   // CheckVectorCast - check type constraints for vectors. <br>   // Since vectors are an extension, there are no C standard reference for this.<br>   // We allow casting between vectors and integer datatypes of the same size.<br><br>Modified: cfe/trunk/Sema/SemaDecl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=44816&r1=44815&r2=44816&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=44816&r1=44815&r2=44816&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/Sema/SemaDecl.cpp (original)<br>+++ cfe/trunk/Sema/SemaDecl.cpp Mon Dec 10 16:44:33 2007<br>@@ -429,21 +429,75 @@<br> void Sema::CheckVariableInitList(QualType DeclType, InitListExpr *IList, <br>                                  QualType ElementType, bool isStatic, <br>                                  int &nInitializers, bool &hadError) {<br>-  for (unsigned i = 0; i < IList->getNumInits(); i++) {<br>-    Expr *expr = IList->getInit(i);<br>+  unsigned numInits = IList->getNumInits();<br>+<br>+  if (numInits) {<br>+    if (CheckForCharArrayInitializer(IList, ElementType, nInitializers,<br>+                                     false, hadError))<br>+      return;<br>+        <br>+    for (unsigned i = 0; i < numInits; i++) {<br>+      Expr *expr = IList->getInit(i);<br><br>-    if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr)) {<br>-      if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {<br>-        int maxElements = CAT->getMaximumElements();<br>-        CheckConstantInitList(DeclType, InitList, ElementType, isStatic, <br>-                              maxElements, hadError);<br>+      if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr)) {<br>+        if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {<br>+          int maxElements = CAT->getMaximumElements();<br>+          CheckConstantInitList(DeclType, InitList, ElementType, isStatic, <br>+                                maxElements, hadError);<br>+        }<br>+      } else {<br>+        hadError = CheckInitExpr(expr, IList, i, isStatic, ElementType);<br>+      }<br>+      nInitializers++;<br>+    }<br>+  } else {<br>+    Diag(IList->getLocStart(),<br>+         diag::err_at_least_one_initializer_needed_to_size_array);<br>+    hadError = true;<br>+  }<br>+}<br>+<br>+bool Sema::CheckForCharArrayInitializer(InitListExpr *IList, <br>+                                        QualType ElementType,<br>+                                        int &nInitializers, bool isConstant,<br>+                                        bool &hadError)<br>+{<br>+  if (ElementType->isPointerType())<br>+    return false;<br>+  <br>+  if (StringLiteral *literal = dyn_cast<StringLiteral>(IList->getInit(0))) {<br>+    // FIXME: Handle wide strings<br>+    if (ElementType->isCharType()) {<br>+      if (isConstant) {<br>+        if (literal->getByteLength() > (unsigned)nInitializers) {<br>+          Diag(literal->getSourceRange().getBegin(),<br>+               diag::warn_initializer_string_for_char_array_too_long,<br>+               literal->getSourceRange());<br>+        }<br>+      } else {<br>+        nInitializers = literal->getByteLength() + 1;<br>       }<br>     } else {<br>-      hadError = CheckInitExpr(expr, IList, i, isStatic, ElementType);<br>+      // FIXME: It might be better if we could point to the declaration<br>+      // here, instead of the string literal.<br>+      Diag(literal->getSourceRange().getBegin(), <br>+           diag::array_of_wrong_type_initialized_from_string,<br>+           ElementType.getAsString());<br>+      hadError = true;<br>     }<br>-    nInitializers++;<br>+    <br>+    // Check for excess initializers<br>+    for (unsigned i = 1; i < IList->getNumInits(); i++) {<br>+      Expr *expr = IList->getInit(i);<br>+      Diag(expr->getLocStart(), <br>+           diag::err_excess_initializers_in_char_array_initializer, <br>+           expr->getSourceRange());<br>+    }<br>+    <br>+    return true;<br>   }<br>-  return;<br>+<br>+  return false;<br> }<br><br> // FIXME: Doesn't deal with arrays of structures yet.<br>@@ -473,6 +527,11 @@<br>   // The empty init list "{ }" is treated specially below.<br>   unsigned numInits = IList->getNumInits();<br>   if (numInits) {<br>+    if (CheckForCharArrayInitializer(IList, ElementType, <br>+                                     maxElementsAtThisLevel,<br>+                                     true, hadError))<br>+      return;<br>+    <br>     for (unsigned i = 0; i < numInits; i++) {<br>       Expr *expr = IList->getInit(i);<br><br>@@ -499,19 +558,42 @@<br>       Diag(IList->getLocStart(), diag::warn_excess_initializers, <br>            IList->getSourceRange());<br>   }<br>-  return;<br> }<br><br> bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {<br>+  bool hadError = false;<br>+  <br>   InitListExpr *InitList = dyn_cast<InitListExpr>(Init);<br>-  if (!InitList)<br>+  if (!InitList) {<br>+    if (StringLiteral *strLiteral = dyn_cast<StringLiteral>(Init)) {<br>+      const VariableArrayType *VAT = DeclType->getAsVariableArrayType();<br>+      // FIXME: Handle wide strings<br>+      if (VAT && VAT->getElementType()->isCharType()) {<br>+        // C99 6.7.8p14. We have an array of character type with unknown size <br>+        // being initialized to a string literal.<br>+        llvm::APSInt ConstVal(32);<br>+        ConstVal = strLiteral->getByteLength() + 1;<br>+        // Return a new array type (C99 6.7.8p22).<br>+        DeclType = Context.getConstantArrayType(VAT->getElementType(), ConstVal, <br>+                                                ArrayType::Normal, 0);<br>+        return hadError;<br>+      }<br>+      const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();<br>+      if (CAT && CAT->getElementType()->isCharType()) {<br>+        // C99 6.7.8p14. We have an array of character type with known size.<br>+        if (strLiteral->getByteLength() > (unsigned)CAT->getMaximumElements()) {<br>+          Diag(strLiteral->getSourceRange().getBegin(),<br>+               diag::warn_initializer_string_for_char_array_too_long,<br>+               strLiteral->getSourceRange());<br>+        }<br>+        return hadError;<br>+      }<br>+    }<br>     return CheckSingleInitializer(Init, isStatic, DeclType);<br>-  <br>+  }<br>   // We have an InitListExpr, make sure we set the type.<br>   Init->setType(DeclType);<br><br>-  bool hadError = false;<br>-  <br>   // C99 6.7.8p3: The type of the entity to be initialized shall be an array<br>   // of unknown size ("[]") or an object type that is not a variable array type.<br>   if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) { <br>@@ -525,13 +607,19 @@<br>     int numInits = 0;<br>     CheckVariableInitList(VAT->getElementType(), InitList, VAT->getBaseType(), <br>                           isStatic, numInits, hadError);<br>-    if (!hadError) {<br>-      // Return a new array type from the number of initializers (C99 6.7.8p22).<br>-      llvm::APSInt ConstVal(32);<br>+    llvm::APSInt ConstVal(32);<br>+    <br>+    if (!hadError)<br>       ConstVal = numInits;<br>-      DeclType = Context.getConstantArrayType(VAT->getElementType(), ConstVal, <br>-                                              ArrayType::Normal, 0);<br>-    }<br>+    <br>+    // Return a new array type from the number of initializers (C99 6.7.8p22).<br>+<br>+    // Note that if there was an error, we will still set the decl type,<br>+    // to an array type with 0 elements. <br>+    // This is to avoid "incomplete type foo[]" errors when we've already<br>+    // reported the real cause of the error.<br>+    DeclType = Context.getConstantArrayType(VAT->getElementType(), ConstVal, <br>+                                            ArrayType::Normal, 0);      <br>     return hadError;<br>   }<br>   if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {<br><br>Modified: cfe/trunk/Sema/SemaExpr.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=44816&r1=44815&r2=44816&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=44816&r1=44815&r2=44816&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/Sema/SemaExpr.cpp (original)<br>+++ cfe/trunk/Sema/SemaExpr.cpp Mon Dec 10 16:44:33 2007<br>@@ -689,15 +689,9 @@<br>   //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");<br>   Expr *literalExpr = static_cast<Expr*>(InitExpr);<br><br>-  // FIXME: This is just a temporary workaround to get <br>-  // test/Parser/compound_literal.c passing. (CheckInitializer does not support<br>-  // initializing a char array from a single string literal).<br>-  if (!literalType->isArrayType() || <br>-      !literalType->getAsArrayType()->getElementType()->isCharType()) {<br>-    // FIXME: add more semantic analysis (C99 6.5.2.5).<br>-    if (CheckInitializer(literalExpr, literalType, false))<br>-      return 0;<br>-  }<br>+  // FIXME: add more semantic analysis (C99 6.5.2.5).<br>+  if (CheckInitializer(literalExpr, literalType, false))<br>+    return 0;<br><br>   return new CompoundLiteralExpr(literalType, literalExpr);<br> }<br><br>Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=44816&r1=44815&r2=44816&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=44816&r1=44815&r2=44816&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)<br>+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Mon Dec 10 16:44:33 2007<br>@@ -605,6 +605,10 @@<br>      "array size is negative")<br> DIAG(ext_typecheck_zero_array_size, EXTENSION,<br>      "zero size arrays are an extension")<br>+DIAG(err_at_least_one_initializer_needed_to_size_array, ERROR,<br>+    "at least one initializer value required to size array")<br>+DIAG(array_of_wrong_type_initialized_from_string, ERROR,<br>+    "array of wrong type '%0' initialized from string constant")<br> DIAG(err_array_size_non_int, ERROR,<br>      "size of array has non-integer type '%0'")<br> DIAG(err_init_element_not_constant, ERROR,<br>@@ -617,6 +621,10 @@<br>      "variable-sized object may not be initialized")<br> DIAG(warn_excess_initializers, EXTENSION,<br>      "excess elements in array initializer")<br>+DIAG(err_excess_initializers_in_char_array_initializer, ERROR,<br>+    "excess elements in char array initializer")<br>+DIAG(warn_initializer_string_for_char_array_too_long, WARNING,<br>+    "initializer-string for char array is too long")<br> DIAG(warn_braces_around_scalar_init, WARNING,<br>      "braces around scalar initializer")<br> DIAG(err_illegal_initializer, ERROR,<br><br>Modified: cfe/trunk/test/Sema/array-constraint.c<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-constraint.c?rev=44816&r1=44815&r2=44816&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-constraint.c?rev=44816&r1=44815&r2=44816&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/test/Sema/array-constraint.c (original)<br>+++ cfe/trunk/test/Sema/array-constraint.c Mon Dec 10 16:44:33 2007<br>@@ -45,7 +45,7 @@<br> void strFunc(char *);<br> const char staticAry[] = "test";<br> int checkStaticAry() { <br>-  strFunc(staticAry); // expected-warning{{passing 'char const []' to 'char *' discards qualifiers}}<br>+  strFunc(staticAry); // expected-warning{{passing 'char const [5]' to 'char *' discards qualifiers}}<br> }<br><br><br><br>Modified: cfe/trunk/test/Sema/array-init.c<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-init.c?rev=44816&r1=44815&r2=44816&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-init.c?rev=44816&r1=44815&r2=44816&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/test/Sema/array-init.c (original)<br>+++ cfe/trunk/test/Sema/array-init.c Mon Dec 10 16:44:33 2007<br>@@ -137,3 +137,28 @@<br>   AryT a = { 1, 2 }, b = { 3, 4, 5 };<br> }<br><br>+static char const xx[] = "test";<br>+static char const yy[5] = "test";<br>+static char const zz[3] = "test"; // expected-warning{{initializer-string for char array is too long}}<br>+<br>+void charArrays()<br>+{<br>+<span class="Apple-tab-span" style="white-space:pre">  </span>static char const test[] = "test";<br>+<span class="Apple-tab-span" style="white-space:pre">     </span>static char const test2[] = { "weird stuff" };<br>+<span class="Apple-tab-span" style="white-space:pre"> </span>static char const test3[] = { "test", "excess stuff" }; // expected-error{{excess elements in char array initializer}}<br>+<br>+  char* cp[] = { "Hello" };<br>+<br>+  char c[] = { "Hello" };<br>+  int l[sizeof(c) == 6 ? 1 : -1];<br>+  <br>+  int i[] = { "Hello "}; // expected-error{{array of wrong type 'int' initialized from string constant}}<br>+  char c2[] = { "Hello", "Good bye" }; //expected-error{{excess elements in char array initializer}}<br>+<br>+  int i2[1] = { "Hello" }; //expected-error{{array of wrong type 'int' initialized from string constant}}<br>+  char c3[5] = { "Hello" };<br>+  char c4[4] = { "Hello" }; //expected-warning{{initializer-string for char array is too long}}<br>+<br>+  int i3[] = {}; //expected-error{{at least one initializer value required to size array}} expected-warning{{use of GNU empty initializer extension}}<br>+}<br>+<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></blockquote></div><br></div></body></html>