From: Eli Friedman Date: Wed, 11 Jun 2008 06:20:39 +0000 (+0000) Subject: Don't crash if we can't find FileEntry info for a typedef, since one X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=54ecfce94bc96947ec2059d35920a9eea3ca8569;p=clang Don't crash if we can't find FileEntry info for a typedef, since one isn't guaranteed to exist. This fixes a crash with conflicting typedefs coming from stdin. This also fixes the crash in PR2406, but doesn't completely fix the issue; it appears there's something strange about the physical location for the definition of int64_t in stdlib.h. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52209 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2d6422fb00..0bab523043 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -230,28 +230,31 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) { // FIXME: Verify the underlying types are equivalent! if (getLangOptions().ObjC1 && isBuiltinObjCType(New)) return Old; - + + if (getLangOptions().Microsoft) return New; + // Redeclaration of a type is a constraint violation (6.7.2.3p1). // Apparently GCC, Intel, and Sun all silently ignore the redeclaration if // *either* declaration is in a system header. The code below implements // this adhoc compatibility rule. FIXME: The following code will not // work properly when compiling ".i" files (containing preprocessed output). SourceManager &SrcMgr = Context.getSourceManager(); + HeaderSearch &HdrInfo = PP.getHeaderSearchInfo(); const FileEntry *OldDeclFile = SrcMgr.getFileEntryForLoc(Old->getLocation()); + if (OldDeclFile) { + DirectoryLookup::DirType OldDirType = HdrInfo.getFileDirFlavor(OldDeclFile); + // Allow reclarations in both SystemHeaderDir and ExternCSystemHeaderDir. + if (OldDirType != DirectoryLookup::NormalHeaderDir) + return New; + } const FileEntry *NewDeclFile = SrcMgr.getFileEntryForLoc(New->getLocation()); - HeaderSearch &HdrInfo = PP.getHeaderSearchInfo(); - DirectoryLookup::DirType OldDirType = HdrInfo.getFileDirFlavor(OldDeclFile); - DirectoryLookup::DirType NewDirType = HdrInfo.getFileDirFlavor(NewDeclFile); - - // Allow reclarations in both SystemHeaderDir and ExternCSystemHeaderDir. - if ((OldDirType != DirectoryLookup::NormalHeaderDir || - NewDirType != DirectoryLookup::NormalHeaderDir) || - getLangOptions().Microsoft) - return New; - - // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope. - // TODO: This is totally simplistic. It should handle merging functions - // together etc, merging extern int X; int X; ... + if (NewDeclFile) { + DirectoryLookup::DirType NewDirType = HdrInfo.getFileDirFlavor(NewDeclFile); + // Allow reclarations in both SystemHeaderDir and ExternCSystemHeaderDir. + if (NewDirType != DirectoryLookup::NormalHeaderDir) + return New; + } + Diag(New->getLocation(), diag::err_redefinition, New->getName()); Diag(Old->getLocation(), diag::err_previous_definition); return New; diff --git a/test/Sema/typedef-redef.c b/test/Sema/typedef-redef.c new file mode 100644 index 0000000000..1b12ae408c --- /dev/null +++ b/test/Sema/typedef-redef.c @@ -0,0 +1,4 @@ +// RUN: clang < %s -fsyntax-only -verify + +#include +typedef unsigned long size_t;