diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 17 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 13 |
2 files changed, 27 insertions, 3 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 56422393e4..32037df958 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -622,6 +622,11 @@ bool LLParser::ParseStandaloneMetadata() { return false; } +static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { + return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) || + (GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility; +} + /// ParseAlias: /// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias' /// OptionalLinkage Aliasee @@ -646,6 +651,10 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, if(!GlobalAlias::isValidLinkage(Linkage)) return Error(LinkageLoc, "invalid linkage type for alias"); + if (!isValidVisibilityForLinkage(Visibility, L)) + return Error(LinkageLoc, + "symbol with local linkage must have default visibility"); + Constant *Aliasee; LocTy AliaseeLoc = Lex.getLoc(); if (Lex.getKind() != lltok::kw_bitcast && @@ -714,6 +723,10 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility, unsigned DLLStorageClass) { + if (!isValidVisibilityForLinkage(Visibility, Linkage)) + return Error(NameLoc, + "symbol with local linkage must have default visibility"); + unsigned AddrSpace; bool IsConstant, UnnamedAddr, IsExternallyInitialized; GlobalVariable::ThreadLocalMode TLM; @@ -3014,6 +3027,10 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return Error(LinkageLoc, "invalid function linkage type"); } + if (!isValidVisibilityForLinkage(Visibility, Linkage)) + return Error(LinkageLoc, + "symbol with local linkage must have default visibility"); + if (!FunctionType::isValidReturnType(RetType)) return Error(RetTypeLoc, "invalid function return type"); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 1b2cf76f3e..d0ce237ee6 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1856,7 +1856,9 @@ error_code BitcodeReader::ParseModule(bool Resume) { Section = SectionTable[Record[5]-1]; } GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; - if (Record.size() > 6) + // Local linkage must have default visibility. + if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage)) + // FIXME: Change to an error if non-default in 4.0. Visibility = GetDecodedVisibility(Record[6]); GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal; @@ -1922,7 +1924,10 @@ error_code BitcodeReader::ParseModule(bool Resume) { return Error(InvalidID); Func->setSection(SectionTable[Record[6]-1]); } - Func->setVisibility(GetDecodedVisibility(Record[7])); + // Local linkage must have default visibility. + if (!Func->hasLocalLinkage()) + // FIXME: Change to an error if non-default in 4.0. + Func->setVisibility(GetDecodedVisibility(Record[7])); if (Record.size() > 8 && Record[8]) { if (Record[8]-1 > GCTable.size()) return Error(InvalidID); @@ -1964,7 +1969,9 @@ error_code BitcodeReader::ParseModule(bool Resume) { GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]), "", nullptr, TheModule); // Old bitcode files didn't have visibility field. - if (Record.size() > 3) + // Local linkage must have default visibility. + if (Record.size() > 3 && !NewGA->hasLocalLinkage()) + // FIXME: Change to an error if non-default in 4.0. NewGA->setVisibility(GetDecodedVisibility(Record[3])); if (Record.size() > 4) NewGA->setDLLStorageClass(GetDecodedDLLStorageClass(Record[4])); |