[Mesa-dev] [PATCH] glsl: Implement GLSL 1.30's literal integer range restrictions.

Paul Berry stereotype441 at gmail.com
Thu Oct 27 11:00:54 PDT 2011


On 26 October 2011 13:00, Eric Anholt <eric at anholt.net> wrote:

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

Reviewed-by: Paul Berry <stereotype441 at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20111027/8da58580/attachment.htm>


More information about the mesa-dev mailing list