aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2016-09-12 20:18:16 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2016-09-12 20:18:16 +0000
commit54dcdb88954b1192b004f8b91fc17a42765c20eb (patch)
tree06828e718304e9c4c4e9aa0de02496b72d3bff1b
parenta313485bbdcdee77b1bf891823f9da8984d76bcc (diff)
downloadgcc-54dcdb88954b1192b004f8b91fc17a42765c20eb.zip
gcc-54dcdb88954b1192b004f8b91fc17a42765c20eb.tar.gz
gcc-54dcdb88954b1192b004f8b91fc17a42765c20eb.tar.bz2
re PR c++/77496 (ICE in instantiate_type, at cp/class.c:8270)
gcc/c-family: 2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/77496 * c-common.c (warn_for_omitted_condop): Also warn for boolean data. gcc/c: 2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/77496 * c-parser.c (c_parser_conditional_expression): Pass the rightmost COMPOUND_EXPR to warn_for_omitted_condop. gcc/cp: 2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/77496 * call.c (build_conditional_expr_1): Call warn_for_omitted_condop. * class.c (instantiate_type): Look through the SAVE_EXPR. gcc/testsuite: 2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/77496 * c-c++-common/warn-ommitted-condop.c: Add more test cases. * g++.dg/ext/pr77496.C: New test. * g++.dg/warn/pr77496.C: New test. From-SVN: r240098
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-common.c16
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-parser.c7
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/class.c7
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/warn-ommitted-condop.c13
-rw-r--r--gcc/testsuite/g++.dg/ext/pr77496.C21
-rw-r--r--gcc/testsuite/g++.dg/warn/pr77496.C21
11 files changed, 101 insertions, 13 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 8ba99f2..71c5e50 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR c++/77496
+ * c-common.c (warn_for_omitted_condop): Also warn for boolean data.
+
2016-09-12 David Malcolm <dmalcolm@redhat.com>
PR c/72858
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 16f6548..2215e29 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -10602,17 +10602,21 @@ fold_offsetof (tree expr)
return convert (size_type_node, fold_offsetof_1 (expr));
}
-/* Warn for A ?: C expressions (with B omitted) where A is a boolean
+/* Warn for A ?: C expressions (with B omitted) where A is a boolean
expression, because B will always be true. */
void
-warn_for_omitted_condop (location_t location, tree cond)
-{
- if (truth_value_p (TREE_CODE (cond)))
- warning_at (location, OPT_Wparentheses,
+warn_for_omitted_condop (location_t location, tree cond)
+{
+ /* In C++ template declarations it can happen that the type is dependent
+ and not yet known, thus TREE_TYPE (cond) == NULL_TREE. */
+ if (truth_value_p (TREE_CODE (cond))
+ || (TREE_TYPE (cond) != NULL_TREE
+ && TREE_CODE (TREE_TYPE (cond)) == BOOLEAN_TYPE))
+ warning_at (location, OPT_Wparentheses,
"the omitted middle operand in ?: will always be %<true%>, "
"suggest explicit middle operand");
-}
+}
/* Give an error for storing into ARG, which is 'const'. USE indicates
how ARG was being used. */
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index a647263..b474de1 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR c++/77496
+ * c-parser.c (c_parser_conditional_expression): Pass the rightmost
+ COMPOUND_EXPR to warn_for_omitted_condop.
+
2016-09-07 David Malcolm <dmalcolm@redhat.com>
* c-lang.c (LANG_HOOKS_GET_SUBSTRING_LOCATION): Use
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 0aba51c..a304424 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -6425,14 +6425,17 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
tree eptype = NULL_TREE;
middle_loc = c_parser_peek_token (parser)->location;
- pedwarn (middle_loc, OPT_Wpedantic,
+ pedwarn (middle_loc, OPT_Wpedantic,
"ISO C forbids omitting the middle term of a ?: expression");
- warn_for_omitted_condop (middle_loc, cond.value);
if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
{
eptype = TREE_TYPE (cond.value);
cond.value = TREE_OPERAND (cond.value, 0);
}
+ tree e = cond.value;
+ while (TREE_CODE (e) == COMPOUND_EXPR)
+ e = TREE_OPERAND (e, 1);
+ warn_for_omitted_condop (middle_loc, e);
/* Make sure first operand is calculated only once. */
exp1.value = c_save_expr (default_conversion (cond.value));
if (eptype)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9480993..f572c85 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR c++/77496
+ * call.c (build_conditional_expr_1): Call warn_for_omitted_condop.
+ * class.c (instantiate_type): Look through the SAVE_EXPR.
+
2016-09-09 Jason Merrill <jason@redhat.com>
Implement P0035R4, C++17 new of over-aligned types.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 167d778..393aab9 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4665,9 +4665,12 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
if (!arg2)
{
if (complain & tf_error)
- pedwarn (loc, OPT_Wpedantic,
+ pedwarn (loc, OPT_Wpedantic,
"ISO C++ forbids omitting the middle term of a ?: expression");
+ if ((complain & tf_warning) && !truth_value_p (TREE_CODE (arg1)))
+ warn_for_omitted_condop (loc, arg1);
+
/* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
if (lvalue_p (arg1))
arg2 = arg1 = cp_stabilize_reference (arg1);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index a4f3c6b..f7147e6 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -8262,7 +8262,12 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
return error_mark_node;
}
- /* There only a few kinds of expressions that may have a type
+ /* If we instantiate a template, and it is a A ?: C expression
+ with omitted B, look through the SAVE_EXPR. */
+ if (TREE_CODE (rhs) == SAVE_EXPR)
+ rhs = TREE_OPERAND (rhs, 0);
+
+ /* There are only a few kinds of expressions that may have a type
dependent on overload resolution. */
gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
|| TREE_CODE (rhs) == COMPONENT_REF
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 10936ad..4fc8377 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR c++/77496
+ * c-c++-common/warn-ommitted-condop.c: Add more test cases.
+ * g++.dg/ext/pr77496.C: New test.
+ * g++.dg/warn/pr77496.C: New test.
+
2016-09-12 David Malcolm <dmalcolm@redhat.com>
PR c/72858
diff --git a/gcc/testsuite/c-c++-common/warn-ommitted-condop.c b/gcc/testsuite/c-c++-common/warn-ommitted-condop.c
index 0726f04..678373f 100644
--- a/gcc/testsuite/c-c++-common/warn-ommitted-condop.c
+++ b/gcc/testsuite/c-c++-common/warn-ommitted-condop.c
@@ -1,11 +1,15 @@
/* { dg-options "-Wparentheses -ftrack-macro-expansion=0" } */
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+
extern void f2 (int);
-void bar (int x, int y, int z)
+void bar (int x, int y, int z, bool b)
{
-#define T(op) f2 (x op y ? : 1)
-#define T2(op) f2 (x op y ? 2 : 1)
+#define T(op) f2 (x op y ? : 1)
+#define T2(op) f2 (x op y ? 2 : 1)
T(<); /* { dg-warning "omitted middle operand" } */
T(>); /* { dg-warning "omitted middle operand" } */
@@ -16,6 +20,8 @@ void bar (int x, int y, int z)
T(||); /* { dg-warning "omitted middle operand" } */
T(&&); /* { dg-warning "omitted middle operand" } */
f2 (!x ? : 1); /* { dg-warning "omitted middle operand" } */
+ f2 ((x,!x) ? : 1); /* { dg-warning "omitted middle operand" } */
+ f2 ((x,y,!x) ? : 1); /* { dg-warning "omitted middle operand" } */
T2(<); /* { dg-bogus "omitted middle operand" } */
T2(>); /* { dg-bogus "omitted middle operand" } */
T2(==); /* { dg-bogus "omitted middle operand" } */
@@ -26,4 +32,5 @@ void bar (int x, int y, int z)
T(*); /* { dg-bogus "omitted middle operand" } */
T(/); /* { dg-bogus "omitted middle operand" } */
T(^); /* { dg-bogus "omitted middle operand" } */
+ f2 (b ? : 1); /* { dg-warning "omitted middle operand" } */
}
diff --git a/gcc/testsuite/g++.dg/ext/pr77496.C b/gcc/testsuite/g++.dg/ext/pr77496.C
new file mode 100644
index 0000000..0b21e0c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/pr77496.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "" }
+
+template <class x>
+class z : x
+{
+public:
+ bool zz () { return false; }
+ int f () { return zz ? : 1; } // { dg-error "cannot convert" }
+};
+
+class t
+{
+};
+
+int
+main ()
+{
+ z<t> x;
+ return x.f ();
+}
diff --git a/gcc/testsuite/g++.dg/warn/pr77496.C b/gcc/testsuite/g++.dg/warn/pr77496.C
new file mode 100644
index 0000000..4b97d09
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pr77496.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "-Wparentheses" }
+
+template <class x>
+class z : x
+{
+public:
+ bool zz () { return false; }
+ int f () { return zz () ? : 1; } // { dg-warning "omitted middle operand" }
+};
+
+class t
+{
+};
+
+int
+main ()
+{
+ z<t> x;
+ return x.f ();
+}