aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-gimplify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/cp-gimplify.c')
-rw-r--r--gcc/cp/cp-gimplify.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index c1691c3..2fbb423 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -900,8 +900,39 @@ struct cp_genericize_data
static tree
cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
{
- tree stmt;
- enum tree_code code;
+ tree stmt = *stmt_p;
+ enum tree_code code = TREE_CODE (stmt);
+
+ switch (code)
+ {
+ case PTRMEM_CST:
+ if (TREE_CODE (PTRMEM_CST_MEMBER (stmt)) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (stmt)))
+ {
+ if (!((hash_set<tree> *) data)->add (stmt))
+ error_at (PTRMEM_CST_LOCATION (stmt),
+ "taking address of an immediate function %qD",
+ PTRMEM_CST_MEMBER (stmt));
+ stmt = *stmt_p = build_zero_cst (TREE_TYPE (stmt));
+ break;
+ }
+ break;
+
+ case ADDR_EXPR:
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (TREE_OPERAND (stmt, 0)))
+ {
+ error_at (EXPR_LOCATION (stmt),
+ "taking address of an immediate function %qD",
+ TREE_OPERAND (stmt, 0));
+ stmt = *stmt_p = build_zero_cst (TREE_TYPE (stmt));
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
*stmt_p = stmt = cp_fold (*stmt_p);
@@ -917,12 +948,16 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
}
code = TREE_CODE (stmt);
- if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE
- || code == OMP_LOOP || code == OMP_TASKLOOP || code == OACC_LOOP)
+ switch (code)
{
tree x;
int i, n;
-
+ case OMP_FOR:
+ case OMP_SIMD:
+ case OMP_DISTRIBUTE:
+ case OMP_LOOP:
+ case OMP_TASKLOOP:
+ case OACC_LOOP:
cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
@@ -961,6 +996,22 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
}
cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
*walk_subtrees = 0;
+ return NULL;
+
+ case IF_STMT:
+ if (IF_STMT_CONSTEVAL_P (stmt))
+ {
+ /* Don't walk THEN_CLAUSE (stmt) for consteval if. IF_COND is always
+ boolean_false_node. */
+ cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL);
+ cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL);
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ break;
+
+ default:
+ break;
}
return NULL;
@@ -1476,14 +1527,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
break;
}
- if (tree fndecl = cp_get_callee_fndecl_nofold (stmt))
- if (DECL_IMMEDIATE_FUNCTION_P (fndecl))
- {
- gcc_assert (source_location_current_p (fndecl));
- *stmt_p = cxx_constant_value (stmt);
- break;
- }
-
if (!wtd->no_sanitize_p
&& sanitize_flags_p ((SANITIZE_NULL
| SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
@@ -2629,6 +2672,14 @@ cp_fold (tree x)
int sv = optimize, nw = sv;
tree callee = get_callee_fndecl (x);
+ if (tree fndecl = cp_get_callee_fndecl_nofold (x))
+ if (DECL_IMMEDIATE_FUNCTION_P (fndecl)
+ && source_location_current_p (fndecl))
+ {
+ x = cxx_constant_value (x);
+ break;
+ }
+
/* Some built-in function calls will be evaluated at compile-time in
fold (). Set optimize to 1 when folding __builtin_constant_p inside
a constexpr function so that fold_builtin_1 doesn't fold it to 0. */