Fix signed integer overflow in GLSL preprocessor left shift
Signed integer overflow is undefined in C++, whereas unsigned integer
overflow is not. Always cast left shift operand to unsigned to avoid
UB.
On common compilers, the behavior was already the same before this
patch, so this patch is done mostly for the benefit of automated fuzz
testing.
BUG=chromium:743136
TEST=angle_unittests
Change-Id: I7aab939036bb19a37f258cef4297b560da3cd9d5
Reviewed-on: https://chromium-review.googlesource.com/704659
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/preprocessor/ExpressionParser.cpp b/src/compiler/preprocessor/ExpressionParser.cpp
index ee20a6f..ede3346 100644
--- a/src/compiler/preprocessor/ExpressionParser.cpp
+++ b/src/compiler/preprocessor/ExpressionParser.cpp
@@ -496,12 +496,9 @@
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_uint16 yyrline[] =
-{
- 0, 108, 108, 115, 116, 127, 127, 148, 148, 169,
- 172, 175, 178, 181, 184, 187, 190, 193, 196, 221,
- 246, 249, 252, 278, 305, 308, 311, 314, 326, 329
-};
+static const yytype_uint16 yyrline[] = {0, 108, 108, 115, 116, 127, 127, 148, 148, 169,
+ 172, 175, 178, 181, 184, 187, 190, 193, 196, 221,
+ 243, 246, 249, 275, 302, 305, 308, 311, 323, 326};
#endif
#if YYDEBUG || YYERROR_VERBOSE || 0
@@ -1537,14 +1534,11 @@
}
(yyval) = static_cast<YYSTYPE>(0);
}
- else if ((yyvsp[-2]) < 0)
- {
- // Logical shift left.
- (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
- }
else
{
- (yyval) = (yyvsp[-2]) << (yyvsp[0]);
+ // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer
+ // overflow, which some tools treat as an error.
+ (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
}
}