[cfe-commits] r43750 - in /cfe/trunk: Sema/SemaDecl.cpp test/Sema/array-declared-as-incorrect-type.c

Chris Lattner sabre at nondot.org
Mon Nov 5 20:28:32 PST 2007


Author: lattner
Date: Mon Nov  5 22:28:31 2007
New Revision: 43750

URL: http://llvm.org/viewvc/llvm-project?rev=43750&view=rev
Log:
Add better validation for array types when merging decls.  Patch
contributed by Oliver Hunt, thanks!

Added:
    cfe/trunk/test/Sema/array-declared-as-incorrect-type.c
Modified:
    cfe/trunk/Sema/SemaDecl.cpp

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=43750&r1=43749&r2=43750&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Nov  5 22:28:31 2007
@@ -254,6 +254,45 @@
   return New;
 }
 
+
+/// hasUndefinedLength - Used by equivalentArrayTypes to determine whether the
+/// the outermost VariableArrayType has no size defined.
+static bool hasUndefinedLength(const ArrayType *Array) {
+  const VariableArrayType *VAT = Array->getAsVariableArrayType();
+  return VAT && !VAT->getSizeExpr();
+}
+
+/// equivalentArrayTypes - Used to determine whether two array types are 
+/// equivalent.
+/// We need to check this explicitly as an incomplete array definition is
+/// considered a VariableArrayType, so will not match a complete array 
+/// definition that would be otherwise equivalent.
+static bool areEquivalentArrayTypes(QualType NewQType, QualType OldQType) {
+  const ArrayType *NewAT = NewQType->getAsArrayType();
+  const ArrayType *OldAT = OldQType->getAsArrayType();
+
+  if (!NewAT || !OldAT)
+    return false;
+  
+  // If either (or both) array types in incomplete we need to strip off the
+  // outer VariableArrayType.  Once the outer VAT is removed the remaining
+  // types must be identical if the array types are to be considered 
+  // equivalent.
+  // eg. int[][1] and int[1][1] become
+  //     VAT(null, CAT(1, int)) and CAT(1, CAT(1, int))
+  // removing the outermost VAT gives
+  //     CAT(1, int) and CAT(1, int)
+  // which are equal, therefore the array types are equivalent.
+  if (hasUndefinedLength(NewAT) || hasUndefinedLength(OldAT)) {
+    if (NewAT->getIndexTypeQualifier() != OldAT->getIndexTypeQualifier())
+      return false;
+    NewQType = NewAT->getElementType();
+    OldQType = OldAT->getElementType();
+  }
+  
+  return NewQType == OldQType;
+}
+
 /// MergeVarDecl - We just parsed a variable 'New' which has the same name
 /// and scope as a previous declaration 'Old'.  Figure out how to resolve this
 /// situation, merging decls or emitting diagnostics as appropriate.
@@ -282,7 +321,8 @@
       OldIsTentative = true;
   }
   // Verify the types match.
-  if (Old->getCanonicalType() != New->getCanonicalType()) {
+  if (Old->getCanonicalType() != New->getCanonicalType() && 
+      !areEquivalentArrayTypes(New->getCanonicalType(), Old->getCanonicalType())) {
     Diag(New->getLocation(), diag::err_redefinition, New->getName());
     Diag(Old->getLocation(), diag::err_previous_definition);
     return New;

Added: cfe/trunk/test/Sema/array-declared-as-incorrect-type.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-declared-as-incorrect-type.c?rev=43750&view=auto

==============================================================================
--- cfe/trunk/test/Sema/array-declared-as-incorrect-type.c (added)
+++ cfe/trunk/test/Sema/array-declared-as-incorrect-type.c Mon Nov  5 22:28:31 2007
@@ -0,0 +1,16 @@
+// RUN: clang -fsyntax-only -verify -pedantic %s
+
+extern int a1[];
+int a1[1];
+
+extern int a2[]; // expected-error {{previous definition is here}}
+float a2[1]; // expected-error {{redefinition of 'a2'}}
+
+extern int a3[][2];
+int a3[1][2];
+
+extern int a4[][2]; // expected-error {{previous definition is here}}
+int a4[2]; // expected-error {{redefinition of 'a4'}}
+
+extern int a5[1][2][3]; // expected-error {{previous definition is here}}
+int a5[3][2][1]; // expected-error {{redefinition of 'a5'}}





More information about the cfe-commits mailing list