[llvm-commits] [llvm] r66394 - in /llvm/trunk/lib/AsmParser: LLParser.cpp LLParser.h

Chris Lattner sabre at nondot.org
Sun Mar 8 21:49:14 PDT 2009


Author: lattner
Date: Sun Mar  8 23:49:14 2009
New Revision: 66394

URL: http://llvm.org/viewvc/llvm-project?rev=66394&view=rev
Log:
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}
           ^




Modified:
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=66394&r1=66393&r2=66394&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Sun Mar  8 23:49:14 2009
@@ -235,10 +235,6 @@
  
   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 @@
       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 @@
       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 @@
 //===----------------------------------------------------------------------===//
 
 /// 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 @@
     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 @@
       
       // 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 @@
   }
 
   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 @@
   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 @@
       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 @@
 
   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::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 @@
   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 @@
   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))

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=66394&r1=66393&r2=66394&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Sun Mar  8 23:49:14 2009
@@ -139,10 +139,10 @@
     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);





More information about the llvm-commits mailing list