From: Chris Lattner Date: Wed, 15 Oct 2008 06:16:45 +0000 (+0000) Subject: Fix the .ll grammar rules to allow any type before an 'i32', not just an X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c7e3069bfa8d505cf25637b35a5f518ac616850d;p=oota-llvm.git Fix the .ll grammar rules to allow any type before an 'i32', not just an integer type. Invalid things like 'float 42' are now rejected by the semantic analysis in the productions not the parser. This fixes PR2733. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57560 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 34c7f98f297..0e36286ab42 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1071,7 +1071,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { // Built in types... %type Types ResultTypes -%type FPType PrimType // Classifications +%type PrimType // Classifications %token VOID INTTYPE %token FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL %token TYPE @@ -1165,10 +1165,6 @@ FPredicates | FALSETOK { $$ = FCmpInst::FCMP_FALSE; } ; -// These are some types that allow classification if we only want a particular -// thing... for example, only a signed, unsigned, or integral type. -FPType : FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80; - LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ; OptLocalName : LocalName | /*empty*/ { $$ = 0; }; @@ -1882,61 +1878,82 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr delete $1; CHECK_FOR_ERROR } - | INTTYPE ESINT64VAL { // integral constants - if (!ConstantInt::isValueValidForType($1, $2)) - GEN_ERROR("Constant value doesn't fit in type"); - $$ = ConstantInt::get($1, $2, true); + | Types ESINT64VAL { // integral constants + if (IntegerType *IT = dyn_cast($1->get())) { + if (!ConstantInt::isValueValidForType(IT, $2)) + GEN_ERROR("Constant value doesn't fit in type"); + $$ = ConstantInt::get(IT, $2, true); + } else { + GEN_ERROR("integer constant must have integer type"); + } + delete $1; CHECK_FOR_ERROR } - | INTTYPE ESAPINTVAL { // arbitrary precision integer constants - uint32_t BitWidth = cast($1)->getBitWidth(); - if ($2->getBitWidth() > BitWidth) { - GEN_ERROR("Constant value does not fit in type"); + | Types ESAPINTVAL { // arbitrary precision integer constants + if (IntegerType *IT = dyn_cast($1->get())) { + if ($2->getBitWidth() > IT->getBitWidth()) + GEN_ERROR("Constant value does not fit in type"); + $2->sextOrTrunc(IT->getBitWidth()); + $$ = ConstantInt::get(*$2); + } else { + GEN_ERROR("integer constant must have integer type"); } - $2->sextOrTrunc(BitWidth); - $$ = ConstantInt::get(*$2); + delete $1; delete $2; CHECK_FOR_ERROR } - | INTTYPE EUINT64VAL { // integral constants - if (!ConstantInt::isValueValidForType($1, $2)) - GEN_ERROR("Constant value doesn't fit in type"); - $$ = ConstantInt::get($1, $2, false); + | Types EUINT64VAL { // integral constants + if (IntegerType *IT = dyn_cast($1->get())) { + if (!ConstantInt::isValueValidForType(IT, $2)) + GEN_ERROR("Constant value doesn't fit in type"); + $$ = ConstantInt::get(IT, $2, false); + } else { + GEN_ERROR("integer constant must have integer type"); + } + delete $1; CHECK_FOR_ERROR } - | INTTYPE EUAPINTVAL { // arbitrary precision integer constants - uint32_t BitWidth = cast($1)->getBitWidth(); - if ($2->getBitWidth() > BitWidth) { - GEN_ERROR("Constant value does not fit in type"); + | Types EUAPINTVAL { // arbitrary precision integer constants + if (IntegerType *IT = dyn_cast($1->get())) { + if ($2->getBitWidth() > IT->getBitWidth()) + GEN_ERROR("Constant value does not fit in type"); + $2->zextOrTrunc(IT->getBitWidth()); + $$ = ConstantInt::get(*$2); + } else { + GEN_ERROR("integer constant must have integer type"); } - $2->zextOrTrunc(BitWidth); - $$ = ConstantInt::get(*$2); + delete $2; + delete $1; CHECK_FOR_ERROR } - | INTTYPE TRUETOK { // Boolean constants - if (cast($1)->getBitWidth() != 1) + | Types TRUETOK { // Boolean constants + if ($1->get() != Type::Int1Ty) GEN_ERROR("Constant true must have type i1"); $$ = ConstantInt::getTrue(); + delete $1; CHECK_FOR_ERROR } - | INTTYPE FALSETOK { // Boolean constants - if (cast($1)->getBitWidth() != 1) + | Types FALSETOK { // Boolean constants + if ($1->get() != Type::Int1Ty) GEN_ERROR("Constant false must have type i1"); $$ = ConstantInt::getFalse(); + delete $1; CHECK_FOR_ERROR } - | FPType FPVAL { // Floating point constants - if (!ConstantFP::isValueValidForType($1, *$2)) + | Types FPVAL { // Floating point constants + if (!ConstantFP::isValueValidForType($1->get(), *$2)) GEN_ERROR("Floating point constant invalid for type"); + // Lexer has no type info, so builds all float and double FP constants // as double. Fix this here. Long double is done right. - if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy) { + if (&$2->getSemantics()==&APFloat::IEEEdouble && $1->get()==Type::FloatTy) { bool ignored; $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &ignored); } $$ = ConstantFP::get(*$2); + delete $1; delete $2; CHECK_FOR_ERROR }; diff --git a/test/Assembler/2008-10-14-NamedTypeOnInteger.ll b/test/Assembler/2008-10-14-NamedTypeOnInteger.ll new file mode 100644 index 00000000000..009489dafd7 --- /dev/null +++ b/test/Assembler/2008-10-14-NamedTypeOnInteger.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis +; PR2733 + +%t1 = type i32 +%t2 = type { %t1 } +@i1 = constant %t2 { %t1 15 }