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
This commit is contained in:
parent
a313485bbd
commit
54dcdb8895
gcc
c-family
c
cp
testsuite
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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" } */
|
||||
}
|
||||
|
21
gcc/testsuite/g++.dg/ext/pr77496.C
Normal file
21
gcc/testsuite/g++.dg/ext/pr77496.C
Normal file
@ -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 ();
|
||||
}
|
21
gcc/testsuite/g++.dg/warn/pr77496.C
Normal file
21
gcc/testsuite/g++.dg/warn/pr77496.C
Normal file
@ -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 ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user