reject 0 element vectors with:
[oota-llvm.git] / lib / AsmParser / LLParser.cpp
index 0708b798adab2cf19e95fb19a9ae9e6b004f50c0..85b4966a7bd7f5260c4345fcdfbd0911b935e80c 100644 (file)
@@ -113,6 +113,7 @@ bool LLParser::ParseTopLevelEntities() {
     // optional leading prefixes, the production is:
     // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
     //               OptionalAddrSpace ('constant'|'global') ...
+    case lltok::kw_private:       // OptionalLinkage
     case lltok::kw_internal:      // OptionalLinkage
     case lltok::kw_weak:          // OptionalLinkage
     case lltok::kw_linkonce:      // OptionalLinkage
@@ -330,8 +331,10 @@ bool LLParser::ParseGlobalType(bool &IsConstant) {
     IsConstant = true;
   else if (Lex.getKind() == lltok::kw_global)
     IsConstant = false;
-  else
+  else {
+    IsConstant = false;
     return TokError("expected 'global' or 'constant'");
+  }
   Lex.Lex();
   return false;
 }
@@ -375,7 +378,8 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
 
   if (Linkage != GlobalValue::ExternalLinkage &&
       Linkage != GlobalValue::WeakLinkage &&
-      Linkage != GlobalValue::InternalLinkage)
+      Linkage != GlobalValue::InternalLinkage &&
+      Linkage != GlobalValue::PrivateLinkage)
     return Error(LinkageLoc, "invalid linkage type for alias");
   
   Constant *Aliasee;
@@ -463,14 +467,15 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
       return true;
   }
 
-  if (isa<FunctionType>(Ty) || Ty == Type::LabelTy)
-    return Error(TyLoc, "invald type for global variable");
+  if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || Ty == Type::VoidTy)
+    return Error(TyLoc, "invalid type for global variable");
   
   GlobalVariable *GV = 0;
 
   // See if the global was forward referenced, if so, use the global.
-  if (!Name.empty() && (GV = M->getGlobalVariable(Name, true))) {
-    if (!ForwardRefVals.erase(Name))
+  if (!Name.empty()) {
+    if ((GV = M->getGlobalVariable(Name, true)) &&
+        !ForwardRefVals.erase(Name))
       return Error(NameLoc, "redefinition of global '@" + Name + "'");
   } else {
     std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
@@ -564,11 +569,18 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty,
   
   // Otherwise, create a new forward reference for this value and remember it.
   GlobalValue *FwdVal;
-  if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
+  if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
+    // Function types can return opaque but functions can't.
+    if (isa<OpaqueType>(FT->getReturnType())) {
+      Error(Loc, "function may not return opaque type");
+      return 0;
+    }
+    
     FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
-  else
+  } else {
     FwdVal = new GlobalVariable(PTy->getElementType(), false,
                                 GlobalValue::ExternalWeakLinkage, 0, Name, M);
+  }
   
   ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
   return FwdVal;
@@ -605,7 +617,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) {
   if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
     // Function types can return opaque but functions can't.
     if (isa<OpaqueType>(FT->getReturnType())) {
-      Error(Loc, "function may not return return opaque type");
+      Error(Loc, "function may not return opaque type");
       return 0;
     }
     FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
@@ -731,6 +743,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
 
 /// ParseOptionalLinkage
 ///   ::= /*empty*/
+///   ::= 'private'
 ///   ::= 'internal'
 ///   ::= 'weak'
 ///   ::= 'linkonce'
@@ -744,6 +757,7 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
   HasLinkage = false;
   switch (Lex.getKind()) {
   default:                    Res = GlobalValue::ExternalLinkage; return false;
+  case lltok::kw_private:     Res = GlobalValue::PrivateLinkage; break;
   case lltok::kw_internal:    Res = GlobalValue::InternalLinkage; break;
   case lltok::kw_weak:        Res = GlobalValue::WeakLinkage; break;
   case lltok::kw_linkonce:    Res = GlobalValue::LinkOnceLinkage; break;
@@ -1012,6 +1026,8 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
     case lltok::star:
       if (Result.get() == Type::LabelTy)
         return TokError("basic block pointers are invalid");
+      if (Result.get() == Type::VoidTy)
+        return TokError("pointers to void are invalid; use i8* instead");
       Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
       Lex.Lex();
       break;
@@ -1020,6 +1036,8 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
     case lltok::kw_addrspace: {
       if (Result.get() == Type::LabelTy)
         return TokError("basic block pointers are invalid");
+      if (Result.get() == Type::VoidTy)
+        return TokError("pointers to void are invalid; use i8* instead");
       unsigned AddrSpace;
       if (ParseOptionalAddrSpace(AddrSpace) ||
           ParseToken(lltok::star, "expected '*' in address space"))
@@ -1244,6 +1262,8 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
     return true;
   
   if (isVector) {
+    if (Size == 0)
+      return Error(SizeLoc, "zero element vector is illegal");
     if ((unsigned)Size != Size)
       return Error(SizeLoc, "size too large for vector");
     if (!EltTy->isFloatingPoint() && !EltTy->isInteger())
@@ -1999,7 +2019,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
     V = PFS.GetVal(ID.UIntVal, Ty, ID.Loc);
   else if (ID.Kind == ValID::t_LocalName)
     V = PFS.GetVal(ID.StrVal, Ty, ID.Loc);
-  else if (ID.Kind == ValID::ValID::t_InlineAsm) {
+  else if (ID.Kind == ValID::t_InlineAsm) {
     const PointerType *PTy = dyn_cast<PointerType>(Ty);
     const FunctionType *FTy =
       PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
@@ -2058,6 +2078,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
     if (isDefine)
       return Error(LinkageLoc, "invalid linkage for function definition");
     break;
+  case GlobalValue::PrivateLinkage:
   case GlobalValue::InternalLinkage:
   case GlobalValue::LinkOnceLinkage:
   case GlobalValue::WeakLinkage:
@@ -2075,11 +2096,21 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
       isa<OpaqueType>(RetType))
     return Error(RetTypeLoc, "invalid function return type");
   
-  if (Lex.getKind() != lltok::GlobalVar)
+  LocTy NameLoc = Lex.getLoc();
+
+  std::string FunctionName;
+  if (Lex.getKind() == lltok::GlobalVar) {
+    FunctionName = Lex.getStrVal();
+  } else if (Lex.getKind() == lltok::GlobalID) {     // @42 is ok.
+    unsigned NameID = Lex.getUIntVal();
+
+    if (NameID != NumberedVals.size())
+      return TokError("function expected to be numbered '%" +
+                      utostr(NumberedVals.size()) + "'");
+  } else {
     return TokError("expected function name");
+  }
   
-  LocTy NameLoc = Lex.getLoc();
-  std::string FunctionName = Lex.getStrVal();
   Lex.Lex();
   
   if (Lex.getKind() != lltok::lparen)
@@ -2936,15 +2967,6 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
   Value *Callee;
   if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
   
-  // Check for call to invalid intrinsic to avoid crashing later.
-  if (Function *F = dyn_cast<Function>(Callee)) {
-    if (F->hasName() && F->getNameLen() >= 5 &&
-        !strncmp(F->getValueName()->getKeyData(), "llvm.", 5) &&
-        !F->getIntrinsicID(true))
-      return Error(CallLoc, "Call to invalid LLVM intrinsic function '" +
-                   F->getNameStr() + "'");
-  }
-  
   // FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
   // function attributes.
   unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg;