On 26 October 2011 13:00, Eric Anholt <span dir="ltr"><<a href="mailto:eric@anholt.net">eric@anholt.net</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">From page 22 (28 of PDF) of GLSL 1.30 spec:<br>
It is an error to provide a literal integer whose magnitude is too<br>
large to store in a variable of matching signed or unsigned type.<br>
<br>
Unsigned integers have exactly 32 bits of precision. Signed integers<br>
use 32 bits, including a sign bit, in two's complement form.<br>
<br>
</div>Fixes piglit int-literal-too-large-0[123].frag.<br>
<br>
v2: Take care with INT_MIN, use stroull, and make it a function.<br>
---<br>
src/glsl/glsl_lexer.ll | 53 ++++++++++++++++++++++++++++++++++++++++-------<br>
1 files changed, 45 insertions(+), 8 deletions(-)<br>
<br>
diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll<br>
index cfd8926..e444536 100644<br>
<div class="im">--- a/src/glsl/glsl_lexer.ll<br>
+++ b/src/glsl/glsl_lexer.ll<br>
@@ -22,6 +22,7 @@<br>
* DEALINGS IN THE SOFTWARE.<br>
*/<br>
#include <ctype.h><br>
+#include <limits.h><br>
#include "strtod.h"<br>
#include "ast.h"<br>
#include "glsl_parser_extras.h"<br>
@@ -43,8 +44,6 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);<br>
<br>
#define YY_USER_INIT yylineno = 0; yycolumn = 0;<br>
<br>
-#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U')<br>
-<br>
/* A macro for handling reserved words and keywords across language versions.<br>
*<br>
* Certain words start out as identifiers, become reserved words in<br>
</div>@@ -81,6 +80,47 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);<br>
<div class="im"> * ...means the word is a legal keyword in GLSL ES 1.00.<br>
*/<br>
#define ES yyextra->es_shader<br>
+<br>
</div>+static int<br>
+literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,<br>
+ YYSTYPE *lval, YYLTYPE *lloc, int base)<br>
+{<br>
+ bool is_uint = (text[len - 1] == 'u' ||<br>
+ text[len - 1] == 'U');<br>
+ const char *digits = text;<br>
+<br>
+ /* Skip "0x" */<br>
<div class="im">+ if (base == 16)<br>
+ digits += 2;<br>
+<br>
</div>+ unsigned long long value = strtoull(digits, NULL, base);<br>
+<br>
+ lval->n = (int)value;<br>
<div class="im">+<br>
+ if (value > UINT_MAX) {<br>
+ /* Note that signed 0xffffffff is valid, not out of range! */<br>
</div>+ if (state->language_version >= 130) {<br>
+ _mesa_glsl_error(lloc, state,<br>
+ "Literal value `%s' out of range", text);<br>
+ } else {<br>
+ _mesa_glsl_warning(lloc, state,<br>
+ "Literal value `%s' out of range", text);<br>
+ }<br>
+ } else if (base == 10 && !is_uint && (unsigned)value > (unsigned)INT_MAX + 1) {<br>
+ /* Tries to catch unintentionally providing a negative value.<br>
+ * Note that -<a href="tel:2147483648" value="+12147483648">2147483648</a> is parsed as -<a href="tel:%282147483648" value="+12147483648">(2147483648</a>), so we don't<br>
+ * want to warn for INT_MAX.<br>
+ */<br>
+ _mesa_glsl_warning(lloc, state,<br>
+ "Signed literal value `%s' is interpreted as %d",<br>
+ text, lval->n);<br>
<div class="im">+ }<br>
+ return is_uint ? UINTCONSTANT : INTCONSTANT;<br>
+}<br>
</div>+<br>
+#define LITERAL_INTEGER(base) \<br>
+ literal_integer(yytext, yyleng, yyextra, yylval, yylloc, base)<br>
<div class="im">+<br>
%}<br>
<br>
%option bison-bridge bison-locations reentrant noyywrap<br>
</div>@@ -292,16 +332,13 @@ layout {<br>
<div class="im"> -= return SUB_ASSIGN;<br>
<br>
[1-9][0-9]*[uU]? {<br>
- yylval->n = strtol(yytext, NULL, 10);<br>
- return IS_UINT ? UINTCONSTANT : INTCONSTANT;<br>
</div>+ return LITERAL_INTEGER(10);<br>
<div class="im"> }<br>
0[xX][0-9a-fA-F]+[uU]? {<br>
- yylval->n = strtol(yytext + 2, NULL, 16);<br>
- return IS_UINT ? UINTCONSTANT : INTCONSTANT;<br>
</div>+ return LITERAL_INTEGER(16);<br>
<div class="im"> }<br>
0[0-7]*[uU]? {<br>
- yylval->n = strtol(yytext, NULL, 8);<br>
- return IS_UINT ? UINTCONSTANT : INTCONSTANT;<br>
</div>+ return LITERAL_INTEGER(8);<br>
<div class="im"> }<br>
<br>
[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {<br>
--<br>
</div>1.7.7<br>
<div><div></div><div class="h5"><br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br>