From: Chris Lattner Date: Wed, 9 Jan 2008 18:47:25 +0000 (+0000) Subject: implement proper support for _Bool in memory, which is usually i8, not i1. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=19009e6fe7e0f51d2e49f4c94928a048c11c5281;p=clang implement proper support for _Bool in memory, which is usually i8, not i1. This fixes a crash reported by Seo Sanghyeon git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGDecl.cpp b/CodeGen/CGDecl.cpp index 69ffbbbfda..23c707d8c4 100644 --- a/CodeGen/CGDecl.cpp +++ b/CodeGen/CGDecl.cpp @@ -71,7 +71,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) { llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); - const llvm::Type *LTy = ConvertType(Ty); + const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty); llvm::Constant *Init = 0; if (D.getInit() == 0) { Init = llvm::Constant::getNullValue(LTy); diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index 866ba47b2a..9a65d2e296 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -121,7 +121,7 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, llvm::Constant *&Entry = GlobalDeclMap[D]; if (Entry) return Entry; - const llvm::Type *Ty = getTypes().ConvertType(D->getType()); + const llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType()); // Check to see if the global already exists. llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName()); diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 0de6dc8b5e..e2a5798ba8 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -149,6 +149,25 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) { return ResultType; } +/// ConvertTypeForMem - Convert type T into a llvm::Type. Maintain and use +/// type cache through TypeHolderMap. This differs from ConvertType in that +/// it is used to convert to the memory representation for a type. For +/// example, the scalar representation for _Bool is i1, but the memory +/// representation is usually i8 or i32, depending on the target. +const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) { + const llvm::Type *R = ConvertType(T); + + // If this is a non-bool type, don't map it. + if (R != llvm::Type::Int1Ty) + return R; + + // Otherwise, return an integer of the target-specified size. + unsigned BoolWidth = (unsigned)Context.getTypeSize(T, SourceLocation()); + return llvm::IntegerType::get(BoolWidth); + +} + + const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { const clang::Type &Ty = *T.getCanonicalType(); @@ -165,8 +184,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { return llvm::IntegerType::get(8); case BuiltinType::Bool: - // FIXME: This is very strange. We want scalars to be i1, but in memory - // they can be i1 or i32. Should the codegen handle this issue? + // Note that we always return bool as i1 for use as a scalar type. return llvm::Type::Int1Ty; case BuiltinType::Char_S: diff --git a/CodeGen/CodeGenTypes.h b/CodeGen/CodeGenTypes.h index 14f896179a..f10dc534ef 100644 --- a/CodeGen/CodeGenTypes.h +++ b/CodeGen/CodeGenTypes.h @@ -118,16 +118,26 @@ public: ASTContext &getContext() const { return Context; } /// ConvertType - Convert type T into a llvm::Type. Maintain and use - /// type cache through TypeHOlderMap. + /// type cache through TypeHolderMap. const llvm::Type *ConvertType(QualType T); - void DecodeArgumentTypes(const FunctionTypeProto &FTP, - std::vector &ArgTys); - + + /// ConvertTypeForMem - Convert type T into a llvm::Type. Maintain and use + /// type cache through TypeHolderMap. This differs from ConvertType in that + /// it is used to convert to the memory representation for a type. For + /// example, the scalar representation for _Bool is i1, but the memory + /// representation is usually i8 or i32, depending on the target. + const llvm::Type *ConvertTypeForMem(QualType T); + + const CGRecordLayout *getCGRecordLayout(const llvm::Type*) const; /// getLLVMFieldNo - Return llvm::StructType element number /// that corresponds to the field FD. unsigned getLLVMFieldNo(const FieldDecl *FD); + +public: // These are internal details of CGT that shouldn't be used externally. + void DecodeArgumentTypes(const FunctionTypeProto &FTP, + std::vector &ArgTys); /// addFieldInfo - Assign field number to field FD. void addFieldInfo(const FieldDecl *FD, unsigned No, unsigned Begin, diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index f22764f93b..c7d6b69fb7 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -233,6 +233,12 @@ public: ///===---- Some helper methods ------------------------------------------===// + unsigned getBoolWidth(FullSourceLoc Loc) { + uint64_t Size; unsigned Align; + getBoolInfo(Size, Align, Loc); + return static_cast(Size); + } + unsigned getCharWidth(FullSourceLoc Loc) { uint64_t Size; unsigned Align; getCharInfo(Size, Align, Loc); diff --git a/test/CodeGen/globalinit.c b/test/CodeGen/globalinit.c index 66bffd3dce..717b0c1cfb 100644 --- a/test/CodeGen/globalinit.c +++ b/test/CodeGen/globalinit.c @@ -26,3 +26,9 @@ char *test(int c) { return c ? buf : bufptr; } + +_Bool booltest = 0; +void booltest2() { + static _Bool booltest3 = 4; +} +