[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