aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c/c-convert.cc3
-rw-r--r--gcc/c/c-tree.h3
-rw-r--r--gcc/c/c-typeck.cc31
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-1.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-10.c9
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-11.c9
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-12.c9
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-2.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-3.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-4.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-5.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-6.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-7.c9
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-8.c9
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111059-9.c9
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111911-1.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111911-2.c11
17 files changed, 130 insertions, 9 deletions
diff --git a/gcc/c/c-convert.cc b/gcc/c/c-convert.cc
index 3e52926..7c1064c 100644
--- a/gcc/c/c-convert.cc
+++ b/gcc/c/c-convert.cc
@@ -150,8 +150,7 @@ c_convert (tree type, tree expr, bool init_const)
case BOOLEAN_TYPE:
convert_to_boolean:
- return fold_convert_loc
- (loc, type, c_objc_common_truthvalue_conversion (input_location, expr));
+ return c_objc_common_truthvalue_conversion (input_location, expr, type);
case POINTER_TYPE:
/* The type nullptr_t may be converted to a pointer type. The result is
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index cf29534..1fba9c8 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -755,7 +755,8 @@ bool c_type_variably_modified_p (tree t)
extern bool char_type_p (tree);
-extern tree c_objc_common_truthvalue_conversion (location_t, tree);
+extern tree c_objc_common_truthvalue_conversion (location_t, tree,
+ tree = integer_type_node);
extern tree require_complete_type (location_t, tree);
extern bool same_translation_unit_p (const_tree, const_tree);
extern int comptypes (tree, tree);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 66c6abc..12d1a5a 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -6363,6 +6363,22 @@ build_c_cast (location_t loc, tree type, tree expr)
" from %qT to %qT", otype, type);
ovalue = value;
+ /* If converting to boolean a value with integer operands that
+ is not itself represented as an INTEGER_CST, the call below
+ to note_integer_operands may insert a C_MAYBE_CONST_EXPR, but
+ build_binary_op as called by c_common_truthvalue_conversion
+ may also insert a C_MAYBE_CONST_EXPR to indicate that a
+ subexpression has been fully folded. To avoid nested
+ C_MAYBE_CONST_EXPR, ensure that
+ c_objc_common_truthvalue_conversion receives an argument
+ properly marked as having integer operands in that case. */
+ if (int_operands
+ && TREE_CODE (value) != INTEGER_CST
+ && (TREE_CODE (type) == BOOLEAN_TYPE
+ || (TREE_CODE (type) == ENUMERAL_TYPE
+ && ENUM_UNDERLYING_TYPE (type) != NULL_TREE
+ && TREE_CODE (ENUM_UNDERLYING_TYPE (type)) == BOOLEAN_TYPE)))
+ value = note_integer_operands (value);
value = convert (type, value);
/* Ignore any integer overflow caused by the cast. */
@@ -13509,11 +13525,11 @@ build_binary_op (location_t location, enum tree_code code,
}
-/* Convert EXPR to be a truth-value, validating its type for this
+/* Convert EXPR to be a truth-value (type TYPE), validating its type for this
purpose. LOCATION is the source location for the expression. */
tree
-c_objc_common_truthvalue_conversion (location_t location, tree expr)
+c_objc_common_truthvalue_conversion (location_t location, tree expr, tree type)
{
bool int_const, int_operands;
@@ -13556,14 +13572,17 @@ c_objc_common_truthvalue_conversion (location_t location, tree expr)
if (int_operands && TREE_CODE (expr) != INTEGER_CST)
{
expr = remove_c_maybe_const_expr (expr);
- expr = build2 (NE_EXPR, integer_type_node, expr,
+ expr = build2 (NE_EXPR, type, expr,
convert (TREE_TYPE (expr), integer_zero_node));
expr = note_integer_operands (expr);
}
else
- /* ??? Should we also give an error for vectors rather than leaving
- those to give errors later? */
- expr = c_common_truthvalue_conversion (location, expr);
+ {
+ /* ??? Should we also give an error for vectors rather than leaving
+ those to give errors later? */
+ expr = c_common_truthvalue_conversion (location, expr);
+ expr = fold_convert_loc (location, type, expr);
+ }
if (TREE_CODE (expr) == INTEGER_CST && int_operands && !int_const)
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-1.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-1.c
new file mode 100644
index 0000000..5788cb4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-1.c
@@ -0,0 +1,5 @@
+void
+f ()
+{
+ (_Bool) (1 << -1);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-10.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-10.c
new file mode 100644
index 0000000..fdd9a29
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-10.c
@@ -0,0 +1,9 @@
+/* { dg-options "-std=gnu23 -Wno-div-by-zero" } */
+
+enum e : bool { X };
+
+enum e
+f ()
+{
+ return 0 / 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-11.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-11.c
new file mode 100644
index 0000000..8126034
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-11.c
@@ -0,0 +1,9 @@
+/* { dg-options "-std=gnu23 -Wno-overflow" } */
+
+enum e : bool { X };
+
+void
+f ()
+{
+ (enum e) (__INT_MAX__ + 1);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-12.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-12.c
new file mode 100644
index 0000000..d11fcf6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-12.c
@@ -0,0 +1,9 @@
+/* { dg-options "-std=gnu23 -Wno-overflow" } */
+
+enum e : bool { X };
+
+enum e
+f ()
+{
+ return __INT_MAX__ + 1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-2.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-2.c
new file mode 100644
index 0000000..785e291
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-2.c
@@ -0,0 +1,5 @@
+void
+f ()
+{
+ (_Bool) (0 / 0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-3.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-3.c
new file mode 100644
index 0000000..21099bc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-3.c
@@ -0,0 +1,5 @@
+_Bool
+f ()
+{
+ return 1 << -1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-4.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-4.c
new file mode 100644
index 0000000..95c68e5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-4.c
@@ -0,0 +1,5 @@
+_Bool
+f ()
+{
+ return 0 / 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-5.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-5.c
new file mode 100644
index 0000000..1047355
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-5.c
@@ -0,0 +1,5 @@
+void
+f ()
+{
+ (_Bool) (__INT_MAX__ + 1);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-6.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-6.c
new file mode 100644
index 0000000..213f79b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-6.c
@@ -0,0 +1,5 @@
+_Bool
+f ()
+{
+ return __INT_MAX__ + 1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-7.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-7.c
new file mode 100644
index 0000000..466f45f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-7.c
@@ -0,0 +1,9 @@
+/* { dg-options "-std=gnu23 -Wno-shift-count-negative" } */
+
+enum e : bool { X };
+
+void
+f ()
+{
+ (enum e) (1 << -1);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-8.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-8.c
new file mode 100644
index 0000000..67f3395
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-8.c
@@ -0,0 +1,9 @@
+/* { dg-options "-std=gnu23 -Wno-div-by-zero" } */
+
+enum e : bool { X };
+
+void
+f ()
+{
+ (enum e) (0 / 0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111059-9.c b/gcc/testsuite/gcc.c-torture/compile/pr111059-9.c
new file mode 100644
index 0000000..f88096d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111059-9.c
@@ -0,0 +1,9 @@
+/* { dg-options "-std=gnu23 -Wno-shift-count-negative" } */
+
+enum e : bool { X };
+
+enum e
+f ()
+{
+ return 1 << -1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111911-1.c b/gcc/testsuite/gcc.c-torture/compile/pr111911-1.c
new file mode 100644
index 0000000..350f4cc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111911-1.c
@@ -0,0 +1,7 @@
+int
+main (void)
+{
+ if (!(_Bool)(__INT_MAX__ + 1) / !(_Bool)(__INT_MAX__ + 1))
+ ;
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111911-2.c b/gcc/testsuite/gcc.c-torture/compile/pr111911-2.c
new file mode 100644
index 0000000..28b69c4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111911-2.c
@@ -0,0 +1,11 @@
+/* { dg-options "-std=gnu23 -Wno-overflow -Wno-div-by-zero" } */
+
+enum e : bool { X };
+
+int
+main (void)
+{
+ if (!(enum e)(__INT_MAX__ + 1) / !(enum e)(__INT_MAX__ + 1))
+ ;
+ return 1;
+}