From f14541626d1c49cb1439d65e81fa3609c23b7cf0 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Mon, 30 Jun 2008 20:45:47 +0000 Subject: [PATCH] Partial handlling of 64-bit integer constants. - Parse integer constants in Thrift files as 64-bit ints. - Die if an overflow occurs. - Warn if an enum value cannot fit in 32 bits. - Add a simple test for the above. I ran all of the generators over BrokenConstants.thrift before adding the overflow, and they appeared to work. However, the code generated was not always valid (for example, the 64-bit constant must have an LL suffix in C++). git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@672907 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/parse/t_const_value.h | 9 +++++---- compiler/cpp/src/thriftl.ll | 19 +++++++++++++++++-- compiler/cpp/src/thrifty.yy | 11 ++++++++++- test/BrokenConstants.thrift | 6 ++++++ 4 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 test/BrokenConstants.thrift diff --git a/compiler/cpp/src/parse/t_const_value.h b/compiler/cpp/src/parse/t_const_value.h index ee658f05..4d5845f1 100644 --- a/compiler/cpp/src/parse/t_const_value.h +++ b/compiler/cpp/src/parse/t_const_value.h @@ -8,6 +8,7 @@ #define T_CONST_VALUE_H #include "t_const.h" +#include #include #include @@ -30,7 +31,7 @@ class t_const_value { t_const_value() {} - t_const_value(int val) { + t_const_value(int64_t val) { set_integer(val); } @@ -47,12 +48,12 @@ class t_const_value { return stringVal_; } - void set_integer(int val) { + void set_integer(int64_t val) { valType_ = CV_INTEGER; intVal_ = val; } - int get_integer() const { + int64_t get_integer() const { return intVal_; } @@ -97,7 +98,7 @@ class t_const_value { std::map mapVal_; std::vector listVal_; std::string stringVal_; - int intVal_; + int64_t intVal_; double doubleVal_; t_const_value_type valType_; diff --git a/compiler/cpp/src/thriftl.ll b/compiler/cpp/src/thriftl.ll index 21a0dd7b..62cdb16c 100644 --- a/compiler/cpp/src/thriftl.ll +++ b/compiler/cpp/src/thriftl.ll @@ -15,6 +15,8 @@ %{ +#include + #include "main.h" #include "globals.h" #include "parse/t_program.h" @@ -30,6 +32,11 @@ void thrift_reserved_keyword(char* keyword) { exit(1); } +void integer_overflow(char* text) { + yyerror("This integer is too big: \"%s\"\n", text); + exit(1); +} + %} /** @@ -181,12 +188,20 @@ st_identifier ([a-zA-Z-][\.a-zA-Z_0-9-]*) "yield" { thrift_reserved_keyword(yytext); } {intconstant} { - yylval.iconst = atoi(yytext); + errno = 0; + yylval.iconst = strtoll(yytext, NULL, 10); + if (errno == ERANGE) { + integer_overflow(yytext); + } return tok_int_constant; } {hexconstant} { - sscanf(yytext+2, "%x", &yylval.iconst); + errno = 0; + yylval.iconst = strtoll(yytext+2, NULL, 16); + if (errno == ERANGE) { + integer_overflow(yytext); + } return tok_int_constant; } diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy index 654c85af..f4ff6ef9 100644 --- a/compiler/cpp/src/thrifty.yy +++ b/compiler/cpp/src/thrifty.yy @@ -13,7 +13,10 @@ * @author Mark Slee */ +#define __STDC_LIMIT_MACROS +#define __STDC_FORMAT_MACROS #include +#include #include "main.h" #include "globals.h" #include "parse/t_program.h" @@ -35,7 +38,7 @@ int g_arglist = 0; */ %union { char* id; - int iconst; + int64_t iconst; double dconst; bool tbool; t_doc* tdoc; @@ -496,6 +499,9 @@ EnumDef: if ($4 < 0) { pwarning(1, "Negative value supplied for enum %s.\n", $2); } + if ($4 > INT_MAX) { + pwarning(1, "64-bit value supplied for enum %s.\n", $2); + } $$ = new t_enum_value($2, $4); if ($1 != NULL) { $$->set_doc($1); @@ -569,6 +575,9 @@ ConstValue: pdebug("ConstValue => tok_int_constant"); $$ = new t_const_value(); $$->set_integer($1); + if ($1 < INT32_MIN || $1 > INT32_MAX) { + pwarning(1, "64-bit constant \"%"PRIi64"\" may not work in all languages.\n", $1); + } } | tok_dub_constant { diff --git a/test/BrokenConstants.thrift b/test/BrokenConstants.thrift new file mode 100644 index 00000000..4c47b338 --- /dev/null +++ b/test/BrokenConstants.thrift @@ -0,0 +1,6 @@ +const i64 myint = 68719476736 +const i64 broken = 9876543210987654321 // A little over 2^63 + +enum foo { + bar = 68719476736 +} -- 2.17.1