aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/expr.c18
-rw-r--r--gcc/cp/pt.c12
-rw-r--r--gcc/cp/typeck.c15
6 files changed, 56 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cd00395..41c5658 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2015-09-03 Martin Sebor <msebor@redhat.com>
+
+ PR c/66516
+ * cp/cp-tree.h (mark_rvalue_use, decay_conversion): Add new
+ argument(s).
+ * cp/expr.c (mark_rvalue_use): Use new argument.
+ * cp/call.c (build_addr_func): Call decay_conversion with new
+ argument.
+ * cp/pt.c (convert_template_argument): Call reject_gcc_builtin.
+ * cp/typeck.c (decay_conversion): Use new argument.
+ (c_decl_implicit): Define.
+
2015-09-02 Balaji V. Iyer <balaji.v.iyer@intel.com>
PR middle-end/60586
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8d4a9e2..367d42b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -288,7 +288,7 @@ build_addr_func (tree function, tsubst_flags_t complain)
function = build_address (function);
}
else
- function = decay_conversion (function, complain);
+ function = decay_conversion (function, complain, /*reject_builtin=*/false);
return function;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4dee60c..784a616 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5787,7 +5787,9 @@ extern tree create_try_catch_expr (tree, tree);
/* in expr.c */
extern tree cplus_expand_constant (tree);
-extern tree mark_rvalue_use (tree);
+extern tree mark_rvalue_use (tree,
+ location_t = UNKNOWN_LOCATION,
+ bool = true);
extern tree mark_lvalue_use (tree);
extern tree mark_type_use (tree);
extern void mark_exp_read (tree);
@@ -6461,7 +6463,9 @@ extern tree cxx_alignas_expr (tree);
extern tree cxx_sizeof_nowarn (tree);
extern tree is_bitfield_expr_with_lowered_type (const_tree);
extern tree unlowered_expr_type (const_tree);
-extern tree decay_conversion (tree, tsubst_flags_t);
+extern tree decay_conversion (tree,
+ tsubst_flags_t,
+ bool = true);
extern tree build_class_member_access_expr (tree, tree, tree, bool,
tsubst_flags_t);
extern tree finish_class_member_access_expr (tree, tree, bool,
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 6d2d658..71dec3d 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -91,18 +91,24 @@ cplus_expand_constant (tree cst)
return cst;
}
-/* Called whenever an expression is used
- in a rvalue context. */
-
+/* Called whenever the expression EXPR is used in an rvalue context.
+ When REJECT_BUILTIN is true the expression is checked to make sure
+ it doesn't make it possible to obtain the address of a GCC built-in
+ function with no library fallback (or any of its bits, such as in
+ a conversion to bool). */
tree
-mark_rvalue_use (tree expr)
+mark_rvalue_use (tree expr,
+ location_t loc /* = UNKNOWN_LOCATION */,
+ bool reject_builtin /* = true */)
{
+ if (reject_builtin && reject_gcc_builtin (expr, loc))
+ return error_mark_node;
+
mark_exp_read (expr);
return expr;
}
-/* Called whenever an expression is used
- in a lvalue context. */
+/* Called whenever an expression is used in an lvalue context. */
tree
mark_lvalue_use (tree expr)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fb7b9d2..ec32c5a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7199,6 +7199,18 @@ convert_template_argument (tree parm,
else if (val == error_mark_node && (complain & tf_error))
error ("could not convert template argument %qE to %qT", orig_arg, t);
+ if (INDIRECT_REF_P (val))
+ {
+ /* Reject template arguments that are references to built-in
+ functions with no library fallbacks. */
+ const_tree inner = TREE_OPERAND (val, 0);
+ if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (inner))) == FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE
+ && reject_gcc_builtin (TREE_OPERAND (inner, 0)))
+ return error_mark_node;
+ }
+
if (TREE_CODE (val) == SCOPE_REF)
{
/* Strip typedefs from the SCOPE_REF. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 83fd34c..388558c 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1911,7 +1911,9 @@ unlowered_expr_type (const_tree exp)
that the return value is no longer an lvalue. */
tree
-decay_conversion (tree exp, tsubst_flags_t complain)
+decay_conversion (tree exp,
+ tsubst_flags_t complain,
+ bool reject_builtin /* = true */)
{
tree type;
enum tree_code code;
@@ -1921,7 +1923,7 @@ decay_conversion (tree exp, tsubst_flags_t complain)
if (type == error_mark_node)
return error_mark_node;
- exp = mark_rvalue_use (exp);
+ exp = mark_rvalue_use (exp, loc, reject_builtin);
exp = resolve_nondeduced_context (exp);
if (type_unknown_p (exp))
@@ -9397,3 +9399,12 @@ check_literal_operator_args (const_tree decl,
return true;
}
}
+
+/* Always returns false since unlike C90, C++ has no concept of implicit
+ function declarations. */
+
+bool
+c_decl_implicit (const_tree)
+{
+ return false;
+}