forked from OSchip/llvm-project
Treat discarding array initializer elements as an extwarn (so -pedantic-errors flags it). Allow CodeGen to truncate the initializer if needed.
llvm-svn: 44518
This commit is contained in:
parent
f45a1d623c
commit
0cbd8723f3
|
@ -22,6 +22,7 @@
|
|||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include <algorithm>
|
||||
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<llvm::CompositeType>(Types.ConvertType(ILE->getType()));
|
||||
assert(CType);
|
||||
std::vector<llvm::Constant*> 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<llvm::ArrayType>(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<llvm::StructType>(CType), Elts);
|
||||
|
||||
// Initialising an array requires us to automatically initialise any
|
||||
// elements that have not been initialised explicitly
|
||||
const llvm::ArrayType *AType = cast<llvm::ArrayType>(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// RUN: clang -emit-llvm %s
|
||||
|
||||
int ary[2] = { 1, 2, 3 };
|
Loading…
Reference in New Issue