mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +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:
parent
c66996ab34
commit
a9a9e07d1c
@ -235,10 +235,6 @@ bool LLParser::ParseUnnamedType() {
|
||||
|
||||
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.
|
||||
std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
|
||||
FI = ForwardRefTypeIDs.find(TypeID);
|
||||
@ -270,10 +266,6 @@ bool LLParser::ParseNamedType() {
|
||||
ParseType(Ty))
|
||||
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.
|
||||
bool AlreadyExists = M->addTypeName(Name, Ty);
|
||||
if (!AlreadyExists) return false;
|
||||
@ -473,7 +465,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
|
||||
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");
|
||||
|
||||
GlobalVariable *GV = 0;
|
||||
@ -873,13 +865,17 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// 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;
|
||||
|
||||
// Verify no unresolved uprefs.
|
||||
if (!UpRefs.empty())
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1140,6 +1136,9 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
|
||||
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
|
||||
ParseOptionalAttrs(Attrs, 0)) return true;
|
||||
|
||||
if (ArgTy == Type::VoidTy)
|
||||
return Error(TypeLoc, "argument can not have void type");
|
||||
|
||||
if (Lex.getKind() == lltok::LocalVar ||
|
||||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
||||
Name = Lex.getStrVal();
|
||||
@ -1160,9 +1159,12 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
|
||||
|
||||
// Otherwise must be an argument type.
|
||||
TypeLoc = Lex.getLoc();
|
||||
if (ParseTypeRec(ArgTy) ||
|
||||
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
|
||||
ParseOptionalAttrs(Attrs, 0)) return true;
|
||||
|
||||
if (ArgTy == Type::VoidTy)
|
||||
return Error(TypeLoc, "argument can not have void type");
|
||||
|
||||
if (Lex.getKind() == lltok::LocalVar ||
|
||||
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
||||
Name = Lex.getStrVal();
|
||||
@ -1233,11 +1235,20 @@ bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
|
||||
}
|
||||
|
||||
std::vector<PATypeHolder> ParamsList;
|
||||
LocTy EltTyLoc = Lex.getLoc();
|
||||
if (ParseTypeRec(Result)) return true;
|
||||
ParamsList.push_back(Result);
|
||||
|
||||
if (Result == Type::VoidTy)
|
||||
return Error(EltTyLoc, "struct element can not have void type");
|
||||
|
||||
while (EatIfPresent(lltok::comma)) {
|
||||
EltTyLoc = Lex.getLoc();
|
||||
if (ParseTypeRec(Result)) return true;
|
||||
|
||||
if (Result == Type::VoidTy)
|
||||
return Error(EltTyLoc, "struct element can not have void type");
|
||||
|
||||
ParamsList.push_back(Result);
|
||||
}
|
||||
|
||||
@ -1272,6 +1283,9 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
|
||||
PATypeHolder EltTy(Type::VoidTy);
|
||||
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,
|
||||
"expected end of sequential type"))
|
||||
return true;
|
||||
@ -2081,7 +2095,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||
ParseOptionalVisibility(Visibility) ||
|
||||
ParseOptionalCallingConv(CC) ||
|
||||
ParseOptionalAttrs(RetAttrs, 1) ||
|
||||
ParseType(RetType, RetTypeLoc))
|
||||
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
|
||||
return true;
|
||||
|
||||
// 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());
|
||||
|
||||
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 PointerType *PFT = PointerType::getUnqual(FT);
|
||||
|
||||
@ -2472,7 +2490,7 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
|
||||
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
||||
PerFunctionState &PFS) {
|
||||
PATypeHolder Ty(Type::VoidTy);
|
||||
if (ParseType(Ty)) return true;
|
||||
if (ParseType(Ty, true /*void allowed*/)) return true;
|
||||
|
||||
if (Ty == Type::VoidTy) {
|
||||
Inst = ReturnInst::Create();
|
||||
@ -2602,7 +2620,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
Value *NormalBB, *UnwindBB;
|
||||
if (ParseOptionalCallingConv(CC) ||
|
||||
ParseOptionalAttrs(RetAttrs, 1) ||
|
||||
ParseType(RetType, RetTypeLoc) ||
|
||||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
|
||||
ParseValID(CalleeID) ||
|
||||
ParseParameterList(ArgList, PFS) ||
|
||||
ParseOptionalAttrs(FnAttrs, 2) ||
|
||||
@ -2960,7 +2978,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
||||
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
|
||||
ParseOptionalCallingConv(CC) ||
|
||||
ParseOptionalAttrs(RetAttrs, 1) ||
|
||||
ParseType(RetType, RetTypeLoc) ||
|
||||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
|
||||
ParseValID(CalleeID) ||
|
||||
ParseParameterList(ArgList, PFS) ||
|
||||
ParseOptionalAttrs(FnAttrs, 2))
|
||||
|
@ -139,10 +139,10 @@ namespace llvm {
|
||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
|
||||
|
||||
// Type Parsing.
|
||||
bool ParseType(PATypeHolder &Result);
|
||||
bool ParseType(PATypeHolder &Result, LocTy &Loc) {
|
||||
bool ParseType(PATypeHolder &Result, bool AllowVoid = false);
|
||||
bool ParseType(PATypeHolder &Result, LocTy &Loc, bool AllowVoid = false) {
|
||||
Loc = Lex.getLoc();
|
||||
return ParseType(Result);
|
||||
return ParseType(Result, AllowVoid);
|
||||
}
|
||||
bool ParseTypeRec(PATypeHolder &H);
|
||||
bool ParseStructType(PATypeHolder &H, bool Packed);
|
||||
|
Loading…
Reference in New Issue
Block a user