]> granicus.if.org Git - clang/commitdiff
Fix ASTContext::typesAreCompatible to allow for int/enum compatibility (C99 6.7.2...
authorSteve Naroff <snaroff@apple.com>
Wed, 9 Jan 2008 22:43:08 +0000 (22:43 +0000)
committerSteve Naroff <snaroff@apple.com>
Wed, 9 Jan 2008 22:43:08 +0000 (22:43 +0000)
Fix Sema::MergeFunctionDecl to allow for function type compatibility (by using the predicate on ASTContext). Function types don't have to be identical to be compatible...

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

AST/ASTContext.cpp
Sema/SemaDecl.cpp
test/Sema/predefined-function.c

index e8e5bcc6ab5873fe887843b45a78176cc70236c3..582babb6f261f93eb982083946a9e19f810deb6c 100644 (file)
@@ -1618,15 +1618,23 @@ bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
   if (rcanon->getTypeClass() == Type::Reference)
     rcanon = cast<ReferenceType>(rcanon)->getReferenceeType();
   
-  // If the canonical type classes don't match, they can't be compatible
+  // If the canonical type classes don't match...
   if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
     // For Objective-C, it is possible for two types to be compatible
     // when their classes don't match (when dealing with "id"). If either type
     // is an interface, we defer to objcTypesAreCompatible(). 
     if (lcanon->isObjCInterfaceType() || rcanon->isObjCInterfaceType())
       return objcTypesAreCompatible(lcanon, rcanon);
+         
+       // C99 6.7.2.2p4: Each enumerated type shall be compatible with char,
+       // a signed integer type, or an unsigned integer type.
+       if ((lcanon->isEnumeralType() && rcanon->isIntegralType()) ||
+           (rcanon->isEnumeralType() && lcanon->isIntegralType()))
+         return true;
+         
     return false;
   }
+  // The canonical type classes match.
   switch (lcanon->getTypeClass()) {
     case Type::Pointer:
       return pointerTypesAreCompatible(lcanon, rcanon);
index 94c65ac93552e244eb670498f1de3a074c199852..7d5fc33161d1d0f831d717f9cd432ecaa66c66e4 100644 (file)
@@ -245,7 +245,9 @@ FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, ScopedDecl *OldD) {
     if (OldQType.getTypePtr()->getTypeClass() == Type::FunctionNoProto && 
         Old->getResultType() == New->getResultType())
       return New;
-    if (OldQType == NewQType)
+    // Function types need to be compatible, not identical. This handles
+    // duplicate function decls like "void f(int); void f(enum X);" properly.
+    if (Context.functionTypesAreCompatible(OldQType, NewQType))
       return New;
   }
 
index bca25fb995bff521e4f2325b79dbd3eb4009d14e..80b5ab0c6bcafba0f4bce8bed75e05b3abcc470e 100644 (file)
@@ -1,5 +1,9 @@
 // RUN: clang -fsyntax-only -verify -pedantic %s
+
+char *funk(int format);
+enum Test {A=-1};
+char *funk(enum Test x);
+
 int foo();
 int foo()
 {