From: Eli Friedman Date: Fri, 15 Feb 2008 06:03:44 +0000 (+0000) Subject: Partial fix for struct compatibility; there's still something messy X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d57405250498a1b5f23c97c6e089318f6f3eefd7;p=clang Partial fix for struct compatibility; there's still something messy going on with mixing scopes, though. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47152 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index d01de2b3a9..d4a689cb2d 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -1555,22 +1555,14 @@ bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) { // C99 6.2.7p1: If both are complete types, then the following additional // requirements apply...FIXME (handle compatibility across source files). bool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) { - TagDecl *ldecl = cast(lhs.getCanonicalType())->getDecl(); - TagDecl *rdecl = cast(rhs.getCanonicalType())->getDecl(); - - if (ldecl->getKind() == Decl::Struct && rdecl->getKind() == Decl::Struct) { - if (ldecl->getIdentifier() == rdecl->getIdentifier()) - return true; - } - if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) { - if (ldecl->getIdentifier() == rdecl->getIdentifier()) - return true; - } // "Class" and "id" are compatible built-in structure types. if (isObjCIdType(lhs) && isObjCClassType(rhs) || isObjCClassType(lhs) && isObjCIdType(rhs)) return true; - return false; + + // Within a translation unit a tag type is + // only compatible with itself. + return lhs.getCanonicalType() == rhs.getCanonicalType(); } bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) { diff --git a/test/Sema/struct-compat.c b/test/Sema/struct-compat.c new file mode 100644 index 0000000000..d63f9cd97c --- /dev/null +++ b/test/Sema/struct-compat.c @@ -0,0 +1,19 @@ +/* RUN: clang %s -fsyntax-only -pedantic -verify + */ + +extern struct {int a;} x; // expected-error{{previous definition is here}} +extern struct {int a;} x; // expected-error{{redefinition of 'x'}} + +struct x; +int a(struct x* b) { +// FIXME: This test currently fails +// Per C99 6.7.2.3, since the outer and inner "struct x"es have different +// scopes, they don't refer to the same type, and are therefore incompatible +struct x {int a;} *c = b; +} + +struct x {int a;} r; +int b() { +// FIXME: This test currently also fails +struct x {char x;} s = r; +}