Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -909,6 +909,12 @@ If a function that has an ``sspstrong`` attribute is inlined into a function that doesn't have an ``sspstrong`` attribute, then the resulting function will have an ``sspstrong`` attribute. +``thread_safety`` + This attribute indicates that the thread safety analysis is enabled + for this function. +``uninitialized_checks`` + This attribute indicates that the checks for uses of uninitialized + memory are enabled. ``uwtable`` This attribute indicates that the ABI being targeted requires that an unwind table entry be produce for this function even if we can Index: include/llvm/IR/Attributes.h =================================================================== --- include/llvm/IR/Attributes.h +++ include/llvm/IR/Attributes.h @@ -95,6 +95,8 @@ StackProtectReq, ///< Stack protection required. StackProtectStrong, ///< Strong Stack protection. StructRet, ///< Hidden pointer to structure to return + ThreadSafety, ///< Thread safety checking is on. + UninitializedChecks, ///< Checking for uses of uninitialized memory is on. UWTable, ///< Function must be in a unwind table ZExt, ///< Zero extended before/after call @@ -478,6 +480,8 @@ .removeAttribute(Attribute::NonLazyBind) .removeAttribute(Attribute::ReturnsTwice) .removeAttribute(Attribute::AddressSafety) + .removeAttribute(Attribute::ThreadSafety) + .removeAttribute(Attribute::UninitializedChecks) .removeAttribute(Attribute::MinSize) .removeAttribute(Attribute::NoDuplicate); } Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp +++ lib/AsmParser/LLLexer.cpp @@ -578,6 +578,8 @@ KEYWORD(ssp); KEYWORD(sspreq); KEYWORD(sspstrong); + KEYWORD(thread_safety); + KEYWORD(uninitialized_checks); KEYWORD(uwtable); KEYWORD(zeroext); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -917,6 +917,8 @@ case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; + case lltok::kw_thread_safety: B.addAttribute(Attribute::ThreadSafety); break; + case lltok::kw_uninitialized_checks: B.addAttribute(Attribute::UninitializedChecks); break; case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; // Error handling. @@ -1156,7 +1158,8 @@ case lltok::kw_noredzone: case lltok::kw_noimplicitfloat: case lltok::kw_naked: case lltok::kw_nonlazybind: case lltok::kw_address_safety: case lltok::kw_minsize: - case lltok::kw_alignstack: + case lltok::kw_alignstack: case lltok::kw_thread_safety: + case lltok::kw_uninitialized_checks: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; } @@ -1198,6 +1201,7 @@ case lltok::kw_nonlazybind: case lltok::kw_address_safety: case lltok::kw_minsize: case lltok::kw_alignstack: case lltok::kw_align: case lltok::kw_noduplicate: + case lltok::kw_thread_safety: case lltok::kw_uninitialized_checks: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; } Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h +++ lib/AsmParser/LLToken.h @@ -119,6 +119,8 @@ kw_sspreq, kw_sspstrong, kw_sret, + kw_thread_safety, + kw_uninitialized_checks, kw_uwtable, kw_zeroext, Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -444,7 +444,7 @@ if (Alignment) B.addAlignmentAttr(Alignment); - B.addRawValue(((EncodedAttrs & (0xffffULL << 32)) >> 11) | + B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) | (EncodedAttrs & 0xffff)); } Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -181,7 +181,7 @@ uint64_t EncodedAttrs = Attrs.Raw(Index) & 0xffff; if (Attrs.hasAttribute(Index, Attribute::Alignment)) EncodedAttrs |= Attrs.getParamAlignment(Index) << 16; - EncodedAttrs |= (Attrs.Raw(Index) & (0xffffULL << 21)) << 11; + EncodedAttrs |= (Attrs.Raw(Index) & (0xfffffULL << 21)) << 11; return EncodedAttrs; } Index: lib/IR/Attributes.cpp =================================================================== --- lib/IR/Attributes.cpp +++ lib/IR/Attributes.cpp @@ -205,6 +205,10 @@ return "sspstrong"; if (hasAttribute(Attribute::StructRet)) return "sret"; + if (hasAttribute(Attribute::ThreadSafety)) + return "thread_safety"; + if (hasAttribute(Attribute::UninitializedChecks)) + return "uninitialized_checks"; if (hasAttribute(Attribute::UWTable)) return "uwtable"; if (hasAttribute(Attribute::ZExt)) @@ -382,6 +386,8 @@ case Attribute::MinSize: return 1ULL << 33; case Attribute::NoDuplicate: return 1ULL << 34; case Attribute::StackProtectStrong: return 1ULL << 35; + case Attribute::ThreadSafety: return 1ULL << 36; + case Attribute::UninitializedChecks: return 1ULL << 37; } llvm_unreachable("Unsupported attribute type"); } Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -651,6 +651,8 @@ !Attrs.hasAttribute(Idx, Attribute::NonLazyBind) && !Attrs.hasAttribute(Idx, Attribute::ReturnsTwice) && !Attrs.hasAttribute(Idx, Attribute::AddressSafety) && + !Attrs.hasAttribute(Idx, Attribute::ThreadSafety) && + !Attrs.hasAttribute(Idx, Attribute::UninitializedChecks) && !Attrs.hasAttribute(Idx, Attribute::MinSize), "Some attributes in '" + Attrs.getAsString(Idx) + "' only apply to functions!", V); Index: test/Bitcode/attributes.ll =================================================================== --- test/Bitcode/attributes.ll +++ test/Bitcode/attributes.ll @@ -162,3 +162,13 @@ { ret void; } +define void @f28() thread_safety +; CHECK: define void @f28() thread_safety +{ + ret void; +} +define void @f29() uninitialized_checks +; CHECK: define void @f29() uninitialized_checks +{ + ret void; +} Index: utils/llvm.grm =================================================================== --- utils/llvm.grm +++ utils/llvm.grm @@ -175,6 +175,8 @@ | returns_twice | nonlazybind | address_safety + | thread_safety + | uninitialized_checks ; OptFuncAttrs ::= + _ | OptFuncAttrs FuncAttr ; Index: utils/vim/llvm.vim =================================================================== --- utils/vim/llvm.vim +++ utils/vim/llvm.vim @@ -55,6 +55,7 @@ syn keyword llvmKeyword sspstrong tail target thread_local to triple syn keyword llvmKeyword unnamed_addr unordered uwtable volatile weak weak_odr syn keyword llvmKeyword x86_fastcallcc x86_stdcallcc x86_thiscallcc zeroext +syn keyword llvmKeyword thread_safety uninitialized_checks " Obsolete keywords. syn keyword llvmError getresult begin end