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