[cfe-commits] r89407 - in /cfe/trunk: lib/AST/Expr.cpp lib/Sema/SemaInit.cpp test/SemaTemplate/dependent-sized_array.cpp
Douglas Gregor
dgregor at apple.com
Thu Nov 19 15:25:22 PST 2009
Author: dgregor
Date: Thu Nov 19 17:25:22 2009
New Revision: 89407
URL: http://llvm.org/viewvc/llvm-project?rev=89407&view=rev
Log:
Deduce a ConstantArrayType from a value-dependent initializer list
rather than punting to a DependentSizedArrayType, tightening up our
type checking for template definitions. Thanks, John!
Modified:
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/SemaTemplate/dependent-sized_array.cpp
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=89407&r1=89406&r2=89407&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Nov 19 17:25:22 2009
@@ -640,12 +640,17 @@
InitListExpr::InitListExpr(SourceLocation lbraceloc,
Expr **initExprs, unsigned numInits,
SourceLocation rbraceloc)
- : Expr(InitListExprClass, QualType(),
- hasAnyTypeDependentArguments(initExprs, numInits),
- hasAnyValueDependentArguments(initExprs, numInits)),
+ : Expr(InitListExprClass, QualType(), false, false),
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
- UnionFieldInit(0), HadArrayRangeDesignator(false) {
-
+ UnionFieldInit(0), HadArrayRangeDesignator(false)
+{
+ for (unsigned I = 0; I != numInits; ++I) {
+ if (initExprs[I]->isTypeDependent())
+ TypeDependent = true;
+ if (initExprs[I]->isValueDependent())
+ ValueDependent = true;
+ }
+
InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
}
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=89407&r1=89406&r2=89407&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Nov 19 17:25:22 2009
@@ -143,12 +143,34 @@
// If the declaration is a non-dependent, incomplete array type
// that has an initializer, then its type will be completed once
- // the initializer is instantiated, meaning that the type is
- // dependent. Morph the declaration's type into a
- // dependently-sized array type.
+ // the initializer is instantiated.
if (!DeclType->isDependentType()) {
if (const IncompleteArrayType *ArrayT
= Context.getAsIncompleteArrayType(DeclType)) {
+ if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
+ if (!ILE->isTypeDependent()) {
+ // Compute the constant array type from the length of the
+ // initializer list.
+ // FIXME: This will be wrong if there are designated
+ // initializations. Good thing they don't exist in C++!
+ llvm::APInt NumElements(Context.getTypeSize(Context.getSizeType()),
+ ILE->getNumInits());
+ llvm::APInt Zero(Context.getTypeSize(Context.getSizeType()), 0);
+ if (NumElements == Zero) {
+ // Sizing an array implicitly to zero is not allowed by ISO C,
+ // but is supported by GNU.
+ Diag(ILE->getLocStart(), diag::ext_typecheck_zero_array_size);
+ }
+
+ DeclType = Context.getConstantArrayType(ArrayT->getElementType(),
+ NumElements,
+ ArrayT->getSizeModifier(),
+ ArrayT->getIndexTypeCVRQualifiers());
+ return false;
+ }
+ }
+
+ // Make the array type-dependent by making it dependently-sized.
DeclType = Context.getDependentSizedArrayType(ArrayT->getElementType(),
/*NumElts=*/0,
ArrayT->getSizeModifier(),
Modified: cfe/trunk/test/SemaTemplate/dependent-sized_array.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-sized_array.cpp?rev=89407&r1=89406&r2=89407&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-sized_array.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-sized_array.cpp Thu Nov 19 17:25:22 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang-cc -fsyntax-only -pedantic -verify %s
template<int N>
void f() {
@@ -8,3 +8,10 @@
template void f<17>();
+
+template<int N>
+void f1() {
+ int a0[] = {}; // expected-warning{{zero}}
+ int a1[] = { 1, 2, 3, N };
+ int a3[sizeof(a1)/sizeof(int) != 4? 1 : -1]; // expected-error{{negative}}
+}
More information about the cfe-commits
mailing list