diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 8 | ||||
-rw-r--r-- | gcc/cp/expr.c | 18 | ||||
-rw-r--r-- | gcc/cp/pt.c | 12 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 15 |
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; +} |