]> granicus.if.org Git - clang/commitdiff
Fix Sema::MergeVarDecl() to better handle type compatibility. The previous code was...
authorSteve Naroff <snaroff@apple.com>
Sat, 9 Aug 2008 16:04:40 +0000 (16:04 +0000)
committerSteve Naroff <snaroff@apple.com>
Sat, 9 Aug 2008 16:04:40 +0000 (16:04 +0000)
Even though the test case this fixes is in "tentative-decls.c", this bug didn't have anything to do with our handling of tentative definitions (which is what I first expected). In any event, this is a tricky area of the spec.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54583 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/Sema/tentative-decls.c

index a96195e525f14edca5e728f8ca3b16665b18854e..da0d1ec85c4f03a9225140c45bf1af32ecc25258 100644 (file)
@@ -378,38 +378,6 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
   return New;
 }
 
-/// 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,
-                                    ASTContext &Context) {
-  const ArrayType *NewAT = Context.getAsArrayType(NewQType);
-  const ArrayType *OldAT = Context.getAsArrayType(OldQType);
-
-  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 (NewAT->isIncompleteArrayType() || OldAT->isIncompleteArrayType()) {
-    if (NewAT->getIndexTypeQualifier() != OldAT->getIndexTypeQualifier())
-      return false;
-    NewQType = Context.getCanonicalType(NewAT->getElementType());
-    OldQType = Context.getCanonicalType(OldAT->getElementType());
-  }
-  
-  return NewQType == OldQType;
-}
-
 /// Predicate for C "tentative" external object definitions (C99 6.9.2).
 bool Sema::isTentativeDefinition(VarDecl *VD) {
   if (VD->isFileVarDecl())
@@ -471,8 +439,7 @@ VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
   // Verify the types match.
   QualType OldCType = Context.getCanonicalType(Old->getType());
   QualType NewCType = Context.getCanonicalType(New->getType());
-  if (OldCType != NewCType &&
-      !areEquivalentArrayTypes(NewCType, OldCType, Context)) {
+  if (OldCType != NewCType && !Context.typesAreCompatible(OldCType, NewCType)) {
     Diag(New->getLocation(), diag::err_redefinition, New->getName());
     Diag(Old->getLocation(), diag::err_previous_definition);
     return New;
index 64f3809e19fc67756baf662003fa2a833ac09c76..7a374e05533e5e924975e20004e9c726b8159bfd 100644 (file)
@@ -24,6 +24,9 @@ int i4;
 int i4;
 extern int i4;
 
+int (*pToArray)[];
+int (*pToArray)[8];
+
 void func() {
   extern int i1; // expected-error{{previous definition is here}}
   static int i1; // expected-error{{static declaration of 'i1' follows non-static declaration}}