From: Christopher Lamb Date: Sun, 2 Dec 2007 08:49:54 +0000 (+0000) Subject: Treat discarding array initializer elements as an extwarn (so -pedantic-errors flags... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce39faa836d0fe2f3be9ff11865c6433f734b2c6;p=clang Treat discarding array initializer elements as an extwarn (so -pedantic-errors flags it). Allow CodeGen to truncate the initializer if needed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44518 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index fdfb883c5e..c5e6a26859 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -22,6 +22,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Intrinsics.h" +#include using namespace clang; using namespace CodeGen; @@ -283,15 +284,29 @@ static llvm::Constant *GenerateAggregateInit(const InitListExpr *ILE, CodeGenTypes& Types = CGM.getTypes(); unsigned NumInitElements = ILE->getNumInits(); + unsigned NumInitableElts = NumInitElements; const llvm::CompositeType *CType = cast(Types.ConvertType(ILE->getType())); assert(CType); std::vector Elts; + // Initialising an array requires us to automatically initialise any + // elements that have not been initialised explicitly + const llvm::ArrayType *AType = 0; + const llvm::Type *AElemTy = 0; + unsigned NumArrayElements = 0; + + // If this is an array, we may have to truncate the initializer + if ((AType = dyn_cast(CType))) { + NumArrayElements = AType->getNumElements(); + AElemTy = AType->getElementType(); + NumInitableElts = std::min(NumInitableElts, NumArrayElements); + } + // Copy initializer elements. unsigned i = 0; - for (i = 0; i < NumInitElements; ++i) { + for (i = 0; i < NumInitableElts; ++i) { llvm::Constant *C = GenerateConstantExpr(ILE->getInit(i), CGM); assert (C && "Failed to create initialiser expression"); Elts.push_back(C); @@ -299,17 +314,14 @@ static llvm::Constant *GenerateAggregateInit(const InitListExpr *ILE, if (ILE->getType()->isStructureType()) return llvm::ConstantStruct::get(cast(CType), Elts); - - // Initialising an array requires us to automatically initialise any - // elements that have not been initialised explicitly - const llvm::ArrayType *AType = cast(CType); + + // Make sure we have an array at this point assert(AType); - const llvm::Type *AElemTy = AType->getElementType(); - unsigned NumArrayElements = AType->getNumElements(); + // Initialize remaining array elements. for (; i < NumArrayElements; ++i) Elts.push_back(llvm::Constant::getNullValue(AElemTy)); - + return llvm::ConstantArray::get(AType, Elts); } diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 8f1945959d..f99239c1e0 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -611,7 +611,7 @@ DIAG(warn_extern_init, WARNING, "'extern' variable has an initializer") DIAG(err_variable_object_no_init, ERROR, "variable-sized object may not be initialized") -DIAG(warn_excess_initializers, WARNING, +DIAG(warn_excess_initializers, EXTENSION, "excess elements in array initializer") DIAG(warn_braces_around_scalar_init, WARNING, "braces around scalar initializer") diff --git a/test/CodeGen/trunc-array-initializer.c b/test/CodeGen/trunc-array-initializer.c new file mode 100644 index 0000000000..6f4caf4588 --- /dev/null +++ b/test/CodeGen/trunc-array-initializer.c @@ -0,0 +1,3 @@ +// RUN: clang -emit-llvm %s + +int ary[2] = { 1, 2, 3 };