mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
Fix two classes of bugs. First:
validate an invariant so that the asmparser rejects a bad construct instead of the verifier. Before: llvm-as: assembly parsed, but does not verify as correct! Invalid struct return type! i64 (%struct.Type*, %struct.Type*)* @foo after: llvm-as: t.ll:5:8: functions with 'sret' argument must return void define i64 @foo(%struct.Type* noalias nocapture sret %agg.result, %struct.Type* nocapture byval %t) nounwind { ^ Second, check that void is only used where allowed (in function return types) not in arbitrary places, fixing PR3747 - Crash in llvm-as with void field in struct. We now reject that example with: $ llvm-as t.ll llvm-as: t.ll:1:12: struct element can not have void type %x = type {void} ^ git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66394 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -235,10 +235,6 @@ bool LLParser::ParseUnnamedType() {
|
|||||||
|
|
||||||
unsigned TypeID = NumberedTypes.size();
|
unsigned TypeID = NumberedTypes.size();
|
||||||
|
|
||||||
// We don't allow assigning names to void type
|
|
||||||
if (Ty == Type::VoidTy)
|
|
||||||
return Error(TypeLoc, "can't assign name to the void type");
|
|
||||||
|
|
||||||
// See if this type was previously referenced.
|
// See if this type was previously referenced.
|
||||||
std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
|
std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
|
||||||
FI = ForwardRefTypeIDs.find(TypeID);
|
FI = ForwardRefTypeIDs.find(TypeID);
|
||||||
@ -270,10 +266,6 @@ bool LLParser::ParseNamedType() {
|
|||||||
ParseType(Ty))
|
ParseType(Ty))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// We don't allow assigning names to void type
|
|
||||||
if (Ty == Type::VoidTy)
|
|
||||||
return Error(NameLoc, "can't assign name '" + Name + "' to the void type");
|
|
||||||
|
|
||||||
// Set the type name, checking for conflicts as we do so.
|
// Set the type name, checking for conflicts as we do so.
|
||||||
bool AlreadyExists = M->addTypeName(Name, Ty);
|
bool AlreadyExists = M->addTypeName(Name, Ty);
|
||||||
if (!AlreadyExists) return false;
|
if (!AlreadyExists) return false;
|
||||||
@ -473,7 +465,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || Ty == Type::VoidTy)
|
if (isa<FunctionType>(Ty) || Ty == Type::LabelTy)
|
||||||
return Error(TyLoc, "invalid type for global variable");
|
return Error(TyLoc, "invalid type for global variable");
|
||||||
|
|
||||||
GlobalVariable *GV = 0;
|
GlobalVariable *GV = 0;
|
||||||
@ -873,13 +865,17 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// ParseType - Parse and resolve a full type.
|
/// ParseType - Parse and resolve a full type.
|
||||||
bool LLParser::ParseType(PATypeHolder &Result) {
|
bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) {
|
||||||
|
LocTy TypeLoc = Lex.getLoc();
|
||||||
if (ParseTypeRec(Result)) return true;
|
if (ParseTypeRec(Result)) return true;
|
||||||
|
|
||||||
// Verify no unresolved uprefs.
|
// Verify no unresolved uprefs.
|
||||||
if (!UpRefs.empty())
|
if (!UpRefs.empty())
|
||||||
return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
|
return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
|
||||||
|
|
||||||
|
if (!AllowVoid && Result.get() == Type::VoidTy)
|
||||||
|
return Error(TypeLoc, "void type only allowed for function results");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,6 +1136,9 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
|
|||||||
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
|
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
|
||||||
ParseOptionalAttrs(Attrs, 0)) return true;
|
ParseOptionalAttrs(Attrs, 0)) return true;
|
||||||
|
|
||||||
|
if (ArgTy == Type::VoidTy)
|
||||||
|
return Error(TypeLoc, "argument can not have void type");
|
||||||
|
|
||||||
if (Lex.getKind() == lltok::LocalVar ||
|
if (Lex.getKind() == lltok::LocalVar ||
|
||||||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
||||||
Name = Lex.getStrVal();
|
Name = Lex.getStrVal();
|
||||||
@ -1160,9 +1159,12 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
|
|||||||
|
|
||||||
// Otherwise must be an argument type.
|
// Otherwise must be an argument type.
|
||||||
TypeLoc = Lex.getLoc();
|
TypeLoc = Lex.getLoc();
|
||||||
if (ParseTypeRec(ArgTy) ||
|
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
|
||||||
ParseOptionalAttrs(Attrs, 0)) return true;
|
ParseOptionalAttrs(Attrs, 0)) return true;
|
||||||
|
|
||||||
|
if (ArgTy == Type::VoidTy)
|
||||||
|
return Error(TypeLoc, "argument can not have void type");
|
||||||
|
|
||||||
if (Lex.getKind() == lltok::LocalVar ||
|
if (Lex.getKind() == lltok::LocalVar ||
|
||||||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
||||||
Name = Lex.getStrVal();
|
Name = Lex.getStrVal();
|
||||||
@ -1233,11 +1235,20 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PATypeHolder> ParamsList;
|
std::vector<PATypeHolder> ParamsList;
|
||||||
|
LocTy EltTyLoc = Lex.getLoc();
|
||||||
if (ParseTypeRec(Result)) return true;
|
if (ParseTypeRec(Result)) return true;
|
||||||
ParamsList.push_back(Result);
|
ParamsList.push_back(Result);
|
||||||
|
|
||||||
|
if (Result == Type::VoidTy)
|
||||||
|
return Error(EltTyLoc, "struct element can not have void type");
|
||||||
|
|
||||||
while (EatIfPresent(lltok::comma)) {
|
while (EatIfPresent(lltok::comma)) {
|
||||||
|
EltTyLoc = Lex.getLoc();
|
||||||
if (ParseTypeRec(Result)) return true;
|
if (ParseTypeRec(Result)) return true;
|
||||||
|
|
||||||
|
if (Result == Type::VoidTy)
|
||||||
|
return Error(EltTyLoc, "struct element can not have void type");
|
||||||
|
|
||||||
ParamsList.push_back(Result);
|
ParamsList.push_back(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1272,6 +1283,9 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
|
|||||||
PATypeHolder EltTy(Type::VoidTy);
|
PATypeHolder EltTy(Type::VoidTy);
|
||||||
if (ParseTypeRec(EltTy)) return true;
|
if (ParseTypeRec(EltTy)) return true;
|
||||||
|
|
||||||
|
if (EltTy == Type::VoidTy)
|
||||||
|
return Error(TypeLoc, "array and vector element type cannot be void");
|
||||||
|
|
||||||
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
|
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
|
||||||
"expected end of sequential type"))
|
"expected end of sequential type"))
|
||||||
return true;
|
return true;
|
||||||
@ -2081,7 +2095,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
|||||||
ParseOptionalVisibility(Visibility) ||
|
ParseOptionalVisibility(Visibility) ||
|
||||||
ParseOptionalCallingConv(CC) ||
|
ParseOptionalCallingConv(CC) ||
|
||||||
ParseOptionalAttrs(RetAttrs, 1) ||
|
ParseOptionalAttrs(RetAttrs, 1) ||
|
||||||
ParseType(RetType, RetTypeLoc))
|
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Verify that the linkage is ok.
|
// Verify that the linkage is ok.
|
||||||
@ -2183,6 +2197,10 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
|||||||
|
|
||||||
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
||||||
|
|
||||||
|
if (PAL.paramHasAttr(1, Attribute::StructRet) &&
|
||||||
|
RetType != Type::VoidTy)
|
||||||
|
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
|
||||||
|
|
||||||
const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg);
|
const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg);
|
||||||
const PointerType *PFT = PointerType::getUnqual(FT);
|
const PointerType *PFT = PointerType::getUnqual(FT);
|
||||||
|
|
||||||
@ -2472,7 +2490,7 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
|
|||||||
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
||||||
PerFunctionState &PFS) {
|
PerFunctionState &PFS) {
|
||||||
PATypeHolder Ty(Type::VoidTy);
|
PATypeHolder Ty(Type::VoidTy);
|
||||||
if (ParseType(Ty)) return true;
|
if (ParseType(Ty, true /*void allowed*/)) return true;
|
||||||
|
|
||||||
if (Ty == Type::VoidTy) {
|
if (Ty == Type::VoidTy) {
|
||||||
Inst = ReturnInst::Create();
|
Inst = ReturnInst::Create();
|
||||||
@ -2602,7 +2620,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
|||||||
Value *NormalBB, *UnwindBB;
|
Value *NormalBB, *UnwindBB;
|
||||||
if (ParseOptionalCallingConv(CC) ||
|
if (ParseOptionalCallingConv(CC) ||
|
||||||
ParseOptionalAttrs(RetAttrs, 1) ||
|
ParseOptionalAttrs(RetAttrs, 1) ||
|
||||||
ParseType(RetType, RetTypeLoc) ||
|
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
|
||||||
ParseValID(CalleeID) ||
|
ParseValID(CalleeID) ||
|
||||||
ParseParameterList(ArgList, PFS) ||
|
ParseParameterList(ArgList, PFS) ||
|
||||||
ParseOptionalAttrs(FnAttrs, 2) ||
|
ParseOptionalAttrs(FnAttrs, 2) ||
|
||||||
@ -2960,7 +2978,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
|||||||
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
|
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
|
||||||
ParseOptionalCallingConv(CC) ||
|
ParseOptionalCallingConv(CC) ||
|
||||||
ParseOptionalAttrs(RetAttrs, 1) ||
|
ParseOptionalAttrs(RetAttrs, 1) ||
|
||||||
ParseType(RetType, RetTypeLoc) ||
|
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
|
||||||
ParseValID(CalleeID) ||
|
ParseValID(CalleeID) ||
|
||||||
ParseParameterList(ArgList, PFS) ||
|
ParseParameterList(ArgList, PFS) ||
|
||||||
ParseOptionalAttrs(FnAttrs, 2))
|
ParseOptionalAttrs(FnAttrs, 2))
|
||||||
|
@ -139,10 +139,10 @@ namespace llvm {
|
|||||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
|
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
|
||||||
|
|
||||||
// Type Parsing.
|
// Type Parsing.
|
||||||
bool ParseType(PATypeHolder &Result);
|
bool ParseType(PATypeHolder &Result, bool AllowVoid = false);
|
||||||
bool ParseType(PATypeHolder &Result, LocTy &Loc) {
|
bool ParseType(PATypeHolder &Result, LocTy &Loc, bool AllowVoid = false) {
|
||||||
Loc = Lex.getLoc();
|
Loc = Lex.getLoc();
|
||||||
return ParseType(Result);
|
return ParseType(Result, AllowVoid);
|
||||||
}
|
}
|
||||||
bool ParseTypeRec(PATypeHolder &H);
|
bool ParseTypeRec(PATypeHolder &H);
|
||||||
bool ParseStructType(PATypeHolder &H, bool Packed);
|
bool ParseStructType(PATypeHolder &H, bool Packed);
|
||||||
|
Reference in New Issue
Block a user