From: Jason Merrill Date: Fri, 4 Jun 2010 21:21:02 +0000 (-0400) Subject: call.c (build_conditional_expr): Never fold in unevaluated context. X-Git-Tag: releases/gcc-4.6.0~6758 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d8a0d13e4fad752b3c3d9ff3f97b03407bf8c726;p=thirdparty%2Fgcc.git call.c (build_conditional_expr): Never fold in unevaluated context. * call.c (build_conditional_expr): Never fold in unevaluated context. * tree.c (build_aggr_init_expr): Propagate TREE_NOTHROW. * semantics.c (simplify_aggr_init_expr): Likewise. * typeck.c (merge_types): Call merge_exception_specifiers. * decl.c (duplicate_decls): Check DECL_SOURCE_LOCATION rather than DECL_ANTICIPATED for preferring new type. From-SVN: r160296 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d77501c11fa..190406e0828f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2010-06-04 Jason Merrill + + * call.c (build_conditional_expr): Never fold in unevaluated context. + * tree.c (build_aggr_init_expr): Propagate TREE_NOTHROW. + * semantics.c (simplify_aggr_init_expr): Likewise. + * typeck.c (merge_types): Call merge_exception_specifiers. + * decl.c (duplicate_decls): Check DECL_SOURCE_LOCATION rather than + DECL_ANTICIPATED for preferring new type. + 2010-06-04 Joseph Myers * g++spec.c (lang_specific_driver): Use GCC-specific formats in diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 60cc4f219dc8..03d188bab2e6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3631,7 +3631,6 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, tree arg2_type; tree arg3_type; tree result = NULL_TREE; - tree result_save; tree result_type = NULL_TREE; bool lvalue_p = true; struct z_candidate *candidates = 0; @@ -4020,12 +4019,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, } valid_operands: - result_save = build3 (COND_EXPR, result_type, arg1, arg2, arg3); - result = fold_if_not_in_template (result_save); - - if (cp_unevaluated_operand && TREE_CODE (result) == CALL_EXPR) - /* Avoid folding to a CALL_EXPR within decltype (c++/42013). */ - result = result_save; + result = build3 (COND_EXPR, result_type, arg1, arg2, arg3); + if (!cp_unevaluated_operand) + /* Avoid folding within decltype (c++/42013) and noexcept. */ + result = fold_if_not_in_template (result); /* We can't use result_type below, as fold might have returned a throw_expr. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 390519618c1a..82182623e95b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1286,7 +1286,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Even if the types match, prefer the new declarations type for built-ins which have not been explicitly declared, for exception lists, etc... */ - else if (DECL_ANTICIPATED (olddecl)) + else if (DECL_SOURCE_LOCATION (olddecl) == BUILTINS_LOCATION) { tree type = TREE_TYPE (newdecl); tree attribs = (*targetm.merge_type_attributes) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 05d1cada9068..2d02690a7177 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3255,6 +3255,7 @@ simplify_aggr_init_expr (tree *tp) fn, aggr_init_expr_nargs (aggr_init_expr), AGGR_INIT_EXPR_ARGP (aggr_init_expr)); + TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr); if (style == ctor) { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 9a5ee0fb2d81..c4b9dd5b5fb7 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -418,6 +418,7 @@ build_aggr_init_expr (tree type, tree init) AGGR_INIT_EXPR_ARGP (init)); TREE_SIDE_EFFECTS (rval) = 1; AGGR_INIT_VIA_CTOR_P (rval) = is_ctor; + TREE_NOTHROW (rval) = TREE_NOTHROW (init); } else rval = init; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 3a7610a41669..a00908e5c381 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -829,26 +829,17 @@ merge_types (tree t1, tree t2) /* Simple way if one arg fails to specify argument types. */ if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node) - { - parms = p2; - raises = TYPE_RAISES_EXCEPTIONS (t2); - } + parms = p2; else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node) - { - parms = p1; - raises = TYPE_RAISES_EXCEPTIONS (t1); - } + parms = p1; else - { - parms = commonparms (p1, p2); - /* In cases where we're merging a real declaration with a - built-in declaration, t1 is the real one. */ - raises = TYPE_RAISES_EXCEPTIONS (t1); - } + parms = commonparms (p1, p2); rval = build_function_type (valtype, parms); gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2)); rval = apply_memfn_quals (rval, type_memfn_quals (t1)); + raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), + TYPE_RAISES_EXCEPTIONS (t2)); t1 = build_exception_variant (rval, raises); break; } @@ -858,7 +849,8 @@ merge_types (tree t1, tree t2) /* Get this value the long way, since TYPE_METHOD_BASETYPE is just the main variant of this. */ tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); - tree raises = TYPE_RAISES_EXCEPTIONS (t1); + tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), + TYPE_RAISES_EXCEPTIONS (t2)); tree t3; /* If this was a member function type, get back to the