]> granicus.if.org Git - clang/commitdiff
Treat discarding array initializer elements as an extwarn (so -pedantic-errors flags...
authorChristopher Lamb <christopher.lamb@gmail.com>
Sun, 2 Dec 2007 08:49:54 +0000 (08:49 +0000)
committerChristopher Lamb <christopher.lamb@gmail.com>
Sun, 2 Dec 2007 08:49:54 +0000 (08:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44518 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CodeGenModule.cpp
include/clang/Basic/DiagnosticKinds.def
test/CodeGen/trunc-array-initializer.c [new file with mode: 0644]

index fdfb883c5eeffb6751c54307c26d9aff776a6c7a..c5e6a26859e135d8ad4893a0650b70f667e421df 100644 (file)
@@ -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);    
 }
 
index 8f1945959db7d19a83666417be424e7045677d4c..f99239c1e082ad423a8b7e7ee20599fb5db05692 100644 (file)
@@ -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 (file)
index 0000000..6f4caf4
--- /dev/null
@@ -0,0 +1,3 @@
+// RUN: clang -emit-llvm %s
+
+int ary[2] = { 1, 2, 3 };