diff options
author | Steve Naroff <snaroff@apple.com> | 2008-01-09 22:43:08 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2008-01-09 22:43:08 +0000 |
commit | 4a74678ed6c3dedac05d02b1ee341f1db869f049 (patch) | |
tree | 6aca62a35994e2d0df92f8b2fed3b42652a204c4 | |
parent | 58d1821279b0ffd002e675d211faca3b5de067e2 (diff) |
Fix ASTContext::typesAreCompatible to allow for int/enum compatibility (C99 6.7.2.2p4).
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
-rw-r--r-- | AST/ASTContext.cpp | 10 | ||||
-rw-r--r-- | Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | test/Sema/predefined-function.c | 6 |
3 files changed, 17 insertions, 3 deletions
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index e8e5bcc6ab..582babb6f2 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -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); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 94c65ac935..7d5fc33161 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -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; } diff --git a/test/Sema/predefined-function.c b/test/Sema/predefined-function.c index bca25fb995..80b5ab0c6b 100644 --- a/test/Sema/predefined-function.c +++ b/test/Sema/predefined-function.c @@ -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() { |