diff options
author | Colin Walters <walters@verbum.org> | 2012-10-26 16:46:05 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2012-10-30 08:20:36 -0400 |
commit | 383b0bdcc8e295d06035768062389797d3ba9262 (patch) | |
tree | e024519716913823e22abcd46294a3dc48bd9acd /giscanner/scannerparser.y | |
parent | ce4a25dc640bdb02ff30fc233abb1c468721cbbd (diff) | |
download | gobject-introspection-383b0bdcc8e295d06035768062389797d3ba9262.tar.gz |
scanner: Correctly handle large 64 bit integer constants
In C, positive integer constants are by default unsigned. This means
an expression like 0x8000000000000000 will be "unsigned long long".
In the actual scanner code, we were parsing them as "gint64", and
storing them as gint64. This was incorrect; we need to parse them
as guint64, and store the bits we get from that. This gives us
an equivalent result to what the C compiler does.
However, when we actually return the value as a Python "long"
(arbitrary length integer), we need to treat the value as unsigned if
the result indicated it was.
https://bugzilla.gnome.org/show_bug.cgi?id=685022
Diffstat (limited to 'giscanner/scannerparser.y')
-rw-r--r-- | giscanner/scannerparser.y | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y index 81a9374f..82ee1d7c 100644 --- a/giscanner/scannerparser.y +++ b/giscanner/scannerparser.y @@ -1,4 +1,4 @@ -/* GObject introspection: C parser +/* GObject introspection: C parser -*- indent-tabs-mode: t; tab-width: 8 -*- * * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it> * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch> @@ -232,15 +232,19 @@ primary_expression } | INTEGER { + char *rest; + guint64 value; $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, scanner->current_filename, lineno); $$->const_int_set = TRUE; if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) { - $$->const_int = g_ascii_strtoll (yytext + 2, NULL, 16); + value = g_ascii_strtoull (yytext + 2, &rest, 16); } else if (g_str_has_prefix (yytext, "0") && strlen (yytext) > 1) { - $$->const_int = g_ascii_strtoll (yytext + 1, NULL, 8); + value = g_ascii_strtoull (yytext + 1, &rest, 8); } else { - $$->const_int = g_ascii_strtoll (yytext, NULL, 10); + value = g_ascii_strtoull (yytext, &rest, 10); } + $$->const_int = value; + $$->const_int_is_unsigned = (rest && (rest[0] == 'U')); } | CHARACTER { |