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...

llvm-svn: 45784
This commit is contained in:
Steve Naroff 2008-01-09 22:43:08 +00:00
parent 436db42a3c
commit c6edcbdb5d
3 changed files with 17 additions and 3 deletions

View 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);

View 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;
}

View 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()
{