diff options
author | Chris Lattner <sabre@nondot.org> | 2008-10-15 06:16:45 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-10-15 06:16:45 +0000 |
commit | c7e3069bfa8d505cf25637b35a5f518ac616850d (patch) | |
tree | 531c10bbd6f8046eb6ca3ad4d5e1030534088ef1 /lib/AsmParser | |
parent | f9078f99d9ee85d710b2aa51134f7b09b1122e72 (diff) | |
download | external_llvm-c7e3069bfa8d505cf25637b35a5f518ac616850d.zip external_llvm-c7e3069bfa8d505cf25637b35a5f518ac616850d.tar.gz external_llvm-c7e3069bfa8d505cf25637b35a5f518ac616850d.tar.bz2 |
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
Diffstat (limited to 'lib/AsmParser')
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 34c7f98..0e36286 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 <TypeVal> Types ResultTypes -%type <PrimType> FPType PrimType // Classifications +%type <PrimType> PrimType // Classifications %token <PrimType> VOID INTTYPE %token <PrimType> 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<IntegerType>($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<IntegerType>($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<IntegerType>($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<IntegerType>($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<IntegerType>($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<IntegerType>($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<IntegerType>($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<IntegerType>($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 }; |