<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>