From 02a5e875cca1ce2f471dad06fb5557346d99c164 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 10 Sep 2011 00:30:18 +0000 Subject: [PATCH] Don't crash when we fail to load a module. It's unbecoming of a well-bred compiler like Clang. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139442 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Serialization/ASTBitCodes.h | 3 + lib/Serialization/ASTReader.cpp | 156 +++++++++++----------- test/Modules/load_failure.c | 4 +- 3 files changed, 85 insertions(+), 78 deletions(-) diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 471937bdb0..0c3e72c081 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -666,6 +666,9 @@ namespace clang { /// \brief Objective-C "SEL" redefinition type SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 8 }; + + /// \brief The number of special type IDs. + const unsigned NumSpecialTypeIDs = 0; /// \brief Predefined declaration IDs. /// diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 5648be8ee5..03efd5bc64 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2788,99 +2788,101 @@ void ASTReader::InitializeContext() { // built-in types. Right now, we just ignore the problem. // Load the special types. - if (Context.getBuiltinVaListType().isNull()) { - Context.setBuiltinVaListType( - GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST])); - } - - if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL]) { - if (Context.ObjCProtoType.isNull()) - Context.ObjCProtoType = GetType(Proto); - } - - if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) { - if (!Context.CFConstantStringTypeDecl) - Context.setCFConstantStringType(GetType(String)); - } - - if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) { - QualType FileType = GetType(File); - if (FileType.isNull()) { - Error("FILE type is NULL"); - return; + if (SpecialTypes.size() > NumSpecialTypeIDs) { + if (Context.getBuiltinVaListType().isNull()) { + Context.setBuiltinVaListType( + GetType(SpecialTypes[SPECIAL_TYPE_BUILTIN_VA_LIST])); } - if (!Context.FILEDecl) { - if (const TypedefType *Typedef = FileType->getAs()) - Context.setFILEDecl(Typedef->getDecl()); - else { - const TagType *Tag = FileType->getAs(); - if (!Tag) { - Error("Invalid FILE type in AST file"); - return; - } - Context.setFILEDecl(Tag->getDecl()); - } + if (unsigned Proto = SpecialTypes[SPECIAL_TYPE_OBJC_PROTOCOL]) { + if (Context.ObjCProtoType.isNull()) + Context.ObjCProtoType = GetType(Proto); } - } - - if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) { - QualType Jmp_bufType = GetType(Jmp_buf); - if (Jmp_bufType.isNull()) { - Error("jmp_buf type is NULL"); - return; + + if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) { + if (!Context.CFConstantStringTypeDecl) + Context.setCFConstantStringType(GetType(String)); } - if (!Context.jmp_bufDecl) { - if (const TypedefType *Typedef = Jmp_bufType->getAs()) - Context.setjmp_bufDecl(Typedef->getDecl()); - else { - const TagType *Tag = Jmp_bufType->getAs(); - if (!Tag) { - Error("Invalid jmp_buf type in AST file"); - return; + if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) { + QualType FileType = GetType(File); + if (FileType.isNull()) { + Error("FILE type is NULL"); + return; + } + + if (!Context.FILEDecl) { + if (const TypedefType *Typedef = FileType->getAs()) + Context.setFILEDecl(Typedef->getDecl()); + else { + const TagType *Tag = FileType->getAs(); + if (!Tag) { + Error("Invalid FILE type in AST file"); + return; + } + Context.setFILEDecl(Tag->getDecl()); } - Context.setjmp_bufDecl(Tag->getDecl()); } } - } - - if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) { - QualType Sigjmp_bufType = GetType(Sigjmp_buf); - if (Sigjmp_bufType.isNull()) { - Error("sigjmp_buf type is NULL"); - return; + + if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_jmp_buf]) { + QualType Jmp_bufType = GetType(Jmp_buf); + if (Jmp_bufType.isNull()) { + Error("jmp_buf type is NULL"); + return; + } + + if (!Context.jmp_bufDecl) { + if (const TypedefType *Typedef = Jmp_bufType->getAs()) + Context.setjmp_bufDecl(Typedef->getDecl()); + else { + const TagType *Tag = Jmp_bufType->getAs(); + if (!Tag) { + Error("Invalid jmp_buf type in AST file"); + return; + } + Context.setjmp_bufDecl(Tag->getDecl()); + } + } } - if (!Context.sigjmp_bufDecl) { - if (const TypedefType *Typedef = Sigjmp_bufType->getAs()) - Context.setsigjmp_bufDecl(Typedef->getDecl()); - else { - const TagType *Tag = Sigjmp_bufType->getAs(); - assert(Tag && "Invalid sigjmp_buf type in AST file"); - Context.setsigjmp_bufDecl(Tag->getDecl()); + if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_sigjmp_buf]) { + QualType Sigjmp_bufType = GetType(Sigjmp_buf); + if (Sigjmp_bufType.isNull()) { + Error("sigjmp_buf type is NULL"); + return; + } + + if (!Context.sigjmp_bufDecl) { + if (const TypedefType *Typedef = Sigjmp_bufType->getAs()) + Context.setsigjmp_bufDecl(Typedef->getDecl()); + else { + const TagType *Tag = Sigjmp_bufType->getAs(); + assert(Tag && "Invalid sigjmp_buf type in AST file"); + Context.setsigjmp_bufDecl(Tag->getDecl()); + } } } - } - if (unsigned ObjCIdRedef - = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) { - if (Context.ObjCIdRedefinitionType.isNull()) - Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef); - } + if (unsigned ObjCIdRedef + = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) { + if (Context.ObjCIdRedefinitionType.isNull()) + Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef); + } - if (unsigned ObjCClassRedef - = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) { - if (Context.ObjCClassRedefinitionType.isNull()) - Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef); - } + if (unsigned ObjCClassRedef + = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) { + if (Context.ObjCClassRedefinitionType.isNull()) + Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef); + } - if (unsigned ObjCSelRedef - = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) { - if (Context.ObjCSelRedefinitionType.isNull()) - Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef); + if (unsigned ObjCSelRedef + = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) { + if (Context.ObjCSelRedefinitionType.isNull()) + Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef); + } } - + ReadPragmaDiagnosticMappings(Context.getDiagnostics()); // If there were any CUDA special declarations, deserialize them. diff --git a/test/Modules/load_failure.c b/test/Modules/load_failure.c index b1f3e0fe79..f034c78739 100644 --- a/test/Modules/load_failure.c +++ b/test/Modules/load_failure.c @@ -10,7 +10,9 @@ __import_module__ load_failure; // RUN: %clang_cc1 -I %T %s -DNONEXISTENT 2>&1 | FileCheck -check-prefix=CHECK-NONEXISTENT %s // CHECK-NONEXISTENT: load_failure.c:2:19: fatal error: module 'load_nonexistent' not found -// RUN: %clang_cc1 -I %T %s -DFAILURE 2>&1 | FileCheck -check-prefix=CHECK-FAILURE %s +// RUN: not %clang_cc1 -I %T %s -DFAILURE 2> %t +// RUN: FileCheck -check-prefix=CHECK-FAILURE %s < %t + // FIXME: Clean up diagnostic text below and give it a location // CHECK-FAILURE: error: C99 support was disabled in PCH file but is currently enabled -- 2.40.0