mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 01:20:56 +08:00
PR c++/91428 - warn about std::is_constant_evaluated in if constexpr.
* cp-tree.h (decl_in_std_namespace_p): Declare. * semantics.c (is_std_constant_evaluated_p): New. (finish_if_stmt_cond): Warn about "std::is_constant_evaluated ()" in an if-constexpr. * typeck.c (decl_in_std_namespace_p): No longer static. * g++.dg/cpp2a/is-constant-evaluated9.C: New test. From-SVN: r274981
This commit is contained in:
parent
4719ac2f2d
commit
14da3939da
gcc
@ -1,3 +1,12 @@
|
||||
2019-08-27 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/91428 - warn about std::is_constant_evaluated in if constexpr.
|
||||
* cp-tree.h (decl_in_std_namespace_p): Declare.
|
||||
* semantics.c (is_std_constant_evaluated_p): New.
|
||||
(finish_if_stmt_cond): Warn about "std::is_constant_evaluated ()" in
|
||||
an if-constexpr.
|
||||
* typeck.c (decl_in_std_namespace_p): No longer static.
|
||||
|
||||
2019-08-26 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* decl.c (duplicate_decls): Always merge DECL_DECLARED_CONSTEXPR_P.
|
||||
|
@ -7496,6 +7496,7 @@ extern tree finish_left_unary_fold_expr (tree, int);
|
||||
extern tree finish_right_unary_fold_expr (tree, int);
|
||||
extern tree finish_binary_fold_expr (tree, tree, int);
|
||||
extern bool treat_lvalue_as_rvalue_p (tree, bool);
|
||||
extern bool decl_in_std_namespace_p (tree);
|
||||
|
||||
/* in typeck2.c */
|
||||
extern void require_complete_eh_spec_types (tree, tree);
|
||||
|
@ -723,6 +723,28 @@ begin_if_stmt (void)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Returns true if FN, a CALL_EXPR, is a call to
|
||||
std::is_constant_evaluated or __builtin_is_constant_evaluated. */
|
||||
|
||||
static bool
|
||||
is_std_constant_evaluated_p (tree fn)
|
||||
{
|
||||
/* std::is_constant_evaluated takes no arguments. */
|
||||
if (call_expr_nargs (fn) != 0)
|
||||
return false;
|
||||
|
||||
tree fndecl = cp_get_callee_fndecl_nofold (fn);
|
||||
if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
|
||||
BUILT_IN_FRONTEND))
|
||||
return true;
|
||||
|
||||
if (!decl_in_std_namespace_p (fndecl))
|
||||
return false;
|
||||
|
||||
tree name = DECL_NAME (fndecl);
|
||||
return name && id_equal (name, "is_constant_evaluated");
|
||||
}
|
||||
|
||||
/* Process the COND of an if-statement, which may be given by
|
||||
IF_STMT. */
|
||||
|
||||
@ -738,6 +760,20 @@ finish_if_stmt_cond (tree cond, tree if_stmt)
|
||||
converted to bool. */
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
|
||||
{
|
||||
/* if constexpr (std::is_constant_evaluated()) is always true,
|
||||
so give the user a clue. */
|
||||
if (warn_tautological_compare)
|
||||
{
|
||||
tree t = cond;
|
||||
if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
|
||||
t = TREE_OPERAND (t, 0);
|
||||
if (TREE_CODE (t) == CALL_EXPR
|
||||
&& is_std_constant_evaluated_p (t))
|
||||
warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
|
||||
"%qs always evaluates to true in %<if constexpr%>",
|
||||
"std::is_constant_evaluated");
|
||||
}
|
||||
|
||||
cond = instantiate_non_dependent_expr (cond);
|
||||
cond = cxx_constant_value (cond, NULL_TREE);
|
||||
}
|
||||
|
@ -9328,7 +9328,7 @@ maybe_warn_about_returning_address_of_local (tree retval)
|
||||
|
||||
/* Returns true if DECL is in the std namespace. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
decl_in_std_namespace_p (tree decl)
|
||||
{
|
||||
return (decl != NULL_TREE
|
||||
|
@ -1,3 +1,8 @@
|
||||
2019-08-27 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/91428 - warn about std::is_constant_evaluated in if constexpr.
|
||||
* g++.dg/cpp2a/is-constant-evaluated9.C: New test.
|
||||
|
||||
2019-08-27 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR tree-optimization/91567
|
||||
|
49
gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C
Normal file
49
gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C
Normal file
@ -0,0 +1,49 @@
|
||||
// PR c++/91428 - warn about std::is_constant_evaluated in if constexpr.
|
||||
// { dg-do compile { target c++2a } }
|
||||
// { dg-options "-Wtautological-compare" }
|
||||
|
||||
namespace std {
|
||||
constexpr inline bool
|
||||
is_constant_evaluated () noexcept
|
||||
{
|
||||
return __builtin_is_constant_evaluated ();
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int
|
||||
foo(int i)
|
||||
{
|
||||
if constexpr (std::is_constant_evaluated ()) // { dg-warning ".std::is_constant_evaluated. always evaluates to true in .if constexpr." }
|
||||
return 42;
|
||||
else
|
||||
return i;
|
||||
}
|
||||
|
||||
constexpr int
|
||||
foo2(int i)
|
||||
{
|
||||
if constexpr (__builtin_is_constant_evaluated ()) // { dg-warning ".std::is_constant_evaluated. always evaluates to true in .if constexpr." }
|
||||
return 42;
|
||||
else
|
||||
return i;
|
||||
}
|
||||
|
||||
constexpr int
|
||||
foo3(int i)
|
||||
{
|
||||
// I is not a constant expression but we short-circuit it.
|
||||
if constexpr (__builtin_is_constant_evaluated () || i)
|
||||
return 42;
|
||||
else
|
||||
return i;
|
||||
}
|
||||
|
||||
constexpr int
|
||||
foo4(int i)
|
||||
{
|
||||
const int j = 0;
|
||||
if constexpr (j && __builtin_is_constant_evaluated ())
|
||||
return 42;
|
||||
else
|
||||
return i;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user