[cfe-commits] r132983 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaType.cpp test/Sema/const-eval.c test/Sema/i-c-e.c test/Sema/struct-decl.c test/Sema/typedef-variable-type.c test/Sema/vla.c test/SemaCXX/c99-variable-l

Eli Friedman eli.friedman at gmail.com
Tue Jun 14 13:57:03 PDT 2011


On Mon, Jun 13, 2011 at 11:38 PM, Chris Lattner <sabre at nondot.org> wrote:
> Author: lattner
> Date: Tue Jun 14 01:38:10 2011
> New Revision: 132983
>
> URL: http://llvm.org/viewvc/llvm-project?rev=132983&view=rev
> Log:
> when compiling in a GNU mode (e.g. gnu99) treat VLAs with a size that can be folded to a constant
> as constant size arrays.  This has slightly different semantics in some insane cases, but allows
> us to accept some constructs that GCC does.  Continue to be pedantic in -std=c99 and other
> modes.  This addressed rdar://8733881 - error "variable-sized object may not be initialized"; g++ accepts same code

http://smooshlab.apple.com:8013/builders/gccTestSuite_clang-x86_64-darwin10-RA__c

-Eli

> Modified:
>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>    cfe/trunk/lib/Sema/SemaType.cpp
>    cfe/trunk/test/Sema/const-eval.c
>    cfe/trunk/test/Sema/i-c-e.c
>    cfe/trunk/test/Sema/struct-decl.c
>    cfe/trunk/test/Sema/typedef-variable-type.c
>    cfe/trunk/test/Sema/vla.c
>    cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 14 01:38:10 2011
> @@ -48,6 +48,8 @@
>   "variable length array declaration can not have 'static' storage duration">;
>  def err_vla_decl_has_extern_linkage : Error<
>   "variable length array declaration can not have 'extern' linkage">;
> +def ext_vla_folded_to_constant : Extension<
> +  "variable length array folded to constant array as an extension">;
>
>  // C99 variably modified types
>  def err_variably_modified_template_arg : Error<
>
> Modified: cfe/trunk/lib/Sema/SemaType.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaType.cpp Tue Jun 14 01:38:10 2011
> @@ -1100,6 +1100,28 @@
>   return Context.getRValueReferenceType(T);
>  }
>
> +/// Check whether the specified array size makes the array type a VLA.  If so,
> +/// return true, if not, return the size of the array in SizeVal.
> +static bool isArraySizeVLA(Expr *ArraySize, llvm::APSInt &SizeVal, Sema &S) {
> +  // If the size is an ICE, it certainly isn't a VLA.
> +  if (ArraySize->isIntegerConstantExpr(SizeVal, S.Context))
> +    return false;
> +
> +  // If we're in a GNU mode (like gnu99, but not c99) accept any evaluatable
> +  // value as an extension.
> +  Expr::EvalResult Result;
> +  if (S.LangOpts.GNUMode && ArraySize->Evaluate(Result, S.Context)) {
> +    if (!Result.hasSideEffects() && Result.Val.isInt()) {
> +      SizeVal = Result.Val.getInt();
> +      S.Diag(ArraySize->getLocStart(), diag::ext_vla_folded_to_constant);
> +      return false;
> +    }
> +  }
> +
> +  return true;
> +}
> +
> +
>  /// \brief Build an array type.
>  ///
>  /// \param T The type of each element in the array.
> @@ -1200,11 +1222,13 @@
>       T = Context.getIncompleteArrayType(T, ASM, Quals);
>   } else if (ArraySize->isTypeDependent() || ArraySize->isValueDependent()) {
>     T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals, Brackets);
> -  } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) ||
> -             (!T->isDependentType() && !T->isIncompleteType() &&
> -              !T->isConstantSizeType())) {
> -    // Per C99, a variable array is an array with either a non-constant
> -    // size or an element type that has a non-constant-size
> +  } else if (!T->isDependentType() && !T->isIncompleteType() &&
> +             !T->isConstantSizeType()) {
> +    // C99: an array with an element type that has a non-constant-size is a VLA.
> +    T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
> +  } else if (isArraySizeVLA(ArraySize, ConstVal, *this)) {
> +    // C99: an array with a non-ICE size is a VLA.  We accept any expression
> +    // that we can fold to a non-zero positive value as an extension.
>     T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
>   } else {
>     // C99 6.7.5.2p1: If the expression is a constant expression, it shall
>
> Modified: cfe/trunk/test/Sema/const-eval.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval.c?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/const-eval.c (original)
> +++ cfe/trunk/test/Sema/const-eval.c Tue Jun 14 01:38:10 2011
> @@ -36,7 +36,7 @@
>  EVAL_EXPR(18, ((int)((void*)10 + 10)) == 20 ? 1 : -1);
>
>  struct s {
> -  int a[(int)-1.0f]; // expected-error {{array size is negative}}
> +  int a[(int)-1.0f]; // expected-error {{'a' declared as an array with a negative size}}
>  };
>
>  EVAL_EXPR(19, ((int)&*(char*)10 == 10 ? 1 : -1));
>
> Modified: cfe/trunk/test/Sema/i-c-e.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/i-c-e.c?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/i-c-e.c (original)
> +++ cfe/trunk/test/Sema/i-c-e.c Tue Jun 14 01:38:10 2011
> @@ -1,4 +1,4 @@
> -// RUN: %clang %s -ffreestanding -fsyntax-only -Xclang -verify -pedantic -fpascal-strings
> +// RUN: %clang %s -ffreestanding -fsyntax-only -Xclang -verify -pedantic -fpascal-strings -std=c99
>
>  #include <stdint.h>
>  #include <limits.h>
>
> Modified: cfe/trunk/test/Sema/struct-decl.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-decl.c?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/struct-decl.c (original)
> +++ cfe/trunk/test/Sema/struct-decl.c Tue Jun 14 01:38:10 2011
> @@ -6,7 +6,7 @@
>
>  struct foo {
>   char name[(int)&((struct bar *)0)->n];
> -  char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{array size is negative}}
> +  char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{'name2' declared as an array with a negative size}}
>  };
>
>  // PR3430
>
> Modified: cfe/trunk/test/Sema/typedef-variable-type.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/typedef-variable-type.c?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/typedef-variable-type.c (original)
> +++ cfe/trunk/test/Sema/typedef-variable-type.c Tue Jun 14 01:38:10 2011
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic -Wno-typedef-redefinition
> +// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic -Wno-typedef-redefinition -std=c99
>
>  // Make sure we accept a single typedef
>  typedef int (*a)[!.0]; // expected-warning{{size of static array must be an integer constant expression}}
>
> Modified: cfe/trunk/test/Sema/vla.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/vla.c?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/vla.c (original)
> +++ cfe/trunk/test/Sema/vla.c Tue Jun 14 01:38:10 2011
> @@ -42,7 +42,7 @@
>  }
>
>  // PR3663
> -static const unsigned array[((2 * (int)((((4) / 2) + 1.0/3.0) * (4) - 1e-8)) + 1)]; // expected-warning {{size of static array must be an integer constant expression}}
> +static const unsigned array[((2 * (int)((((4) / 2) + 1.0/3.0) * (4) - 1e-8)) + 1)]; // expected-warning {{variable length array folded to constant array as an extension}}
>
>  int a[*]; // expected-error {{star modifier used outside of function prototype}}
>  int f4(int a[*][*]);
> @@ -53,7 +53,7 @@
>  int (*pr2044c(void))[pr2044b]; // expected-error {{variably modified type}}
>
>  const int f5_ci = 1;
> -void f5() { char a[][f5_ci] = {""}; } // expected-error {{variable-sized object may not be initialized}}
> +void f5() { char a[][f5_ci] = {""}; } // expected-warning {{variable length array folded to constant array as an extension}}
>
>  // PR5185
>  void pr5185(int a[*]);
>
> Modified: cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp?rev=132983&r1=132982&r2=132983&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp (original)
> +++ cfe/trunk/test/SemaCXX/c99-variable-length-array.cpp Tue Jun 14 01:38:10 2011
> @@ -121,3 +121,12 @@
>     (void)new vla_type; // expected-error{{variably}}
>   }
>  }
> +
> +namespace rdar8733881 { // rdar://8733881
> +
> +static const int k_cVal3 = (int)(1000*0.2f);
> +  int f() {
> +    // Ok, fold to a constant size array as an extension.
> +    char rgch[k_cVal3] = {0};
> +  }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list