From 9e115cec97350099177071bb16b3efcbbacc9445 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 8 Nov 2010 15:17:42 -0500 Subject: [PATCH] Correct conversion/overflow behavior. * cvt.c (ignore_overflows): Move here from typeck.c. (ocp_convert): Use it. (cp_fold_convert): Use it. Don't call rvalue. * typeck.c (build_static_cast_1): Don't use it. Do call rvalue. * error.c (location_of): Handle expressions, too. * class.c (check_bitfield_decl): Set input_location around call to cxx_constant_value. * semantics.c (cxx_eval_outermost_constant_expr): Don't print the expression if it already had TREE_OVERFLOW set. (reduced_constant_expression_p): Check TREE_OVERFLOW_P for C++98, too. (verify_constant): Allow overflow with a permerror if we're enforcing. (cxx_eval_outermost_constant_expr): Use verify_constant. (adjust_temp_type): Use cp_fold_convert. * decl.c (build_enumerator): Don't call constant_expression_warning. * decl2.c (grokbitfield): Likewise. From-SVN: r166453 --- gcc/cp/ChangeLog | 20 +++++++++ gcc/cp/class.c | 3 ++ gcc/cp/cvt.c | 33 ++++++++++++-- gcc/cp/decl.c | 1 - gcc/cp/decl2.c | 1 - gcc/cp/error.c | 4 +- gcc/cp/semantics.c | 32 +++++++++----- gcc/cp/typeck.c | 51 ++++------------------ gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/g++.dg/expr/overflow1.C | 8 ++++ gcc/testsuite/g++.dg/warn/overflow-warn-1.C | 12 +++-- gcc/testsuite/g++.dg/warn/overflow-warn-3.C | 2 +- gcc/testsuite/g++.dg/warn/overflow-warn-4.C | 17 +++++--- gcc/testsuite/g++.dg/warn/overflow-warn-5.C | 8 +++- libstdc++-v3/ChangeLog | 5 +++ .../20_util/ratio/cons/cons_overflow_neg.cc | 2 +- 16 files changed, 132 insertions(+), 75 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/overflow1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1a40ee0..4f08ec3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2010-11-08 Jason Merrill + + Correct conversion/overflow behavior. + * cvt.c (ignore_overflows): Move here from typeck.c. + (ocp_convert): Use it. + (cp_fold_convert): Use it. Don't call rvalue. + * typeck.c (build_static_cast_1): Don't use it. Do call rvalue. + * error.c (location_of): Handle expressions, too. + * class.c (check_bitfield_decl): Set input_location around call to + cxx_constant_value. + * semantics.c (cxx_eval_outermost_constant_expr): Don't + print the expression if it already had TREE_OVERFLOW set. + (reduced_constant_expression_p): Check TREE_OVERFLOW_P for C++98, too. + (verify_constant): Allow overflow with a permerror if we're + enforcing. + (cxx_eval_outermost_constant_expr): Use verify_constant. + (adjust_temp_type): Use cp_fold_convert. + * decl.c (build_enumerator): Don't call constant_expression_warning. + * decl2.c (grokbitfield): Likewise. + 2010-11-06 Jason Merrill PR c++/46348 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 435fa71..03951cf 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2797,11 +2797,14 @@ check_bitfield_decl (tree field) } else { + location_t loc = input_location; /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */ STRIP_NOPS (w); /* detect invalid field size. */ + input_location = DECL_SOURCE_LOCATION (field); w = cxx_constant_value (w); + input_location = loc; if (TREE_CODE (w) != INTEGER_CST) { diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index d2d6f4a..2f7823f 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -543,12 +543,35 @@ force_rvalue (tree expr) } -/* Fold away simple conversions, but make sure the result is an rvalue. */ +/* If EXPR and ORIG are INTEGER_CSTs, return a version of EXPR that has + TREE_OVERFLOW set only if it is set in ORIG. Otherwise, return EXPR + unchanged. */ + +static tree +ignore_overflows (tree expr, tree orig) +{ + if (TREE_CODE (expr) == INTEGER_CST + && TREE_CODE (orig) == INTEGER_CST + && TREE_OVERFLOW (expr) != TREE_OVERFLOW (orig)) + { + gcc_assert (!TREE_OVERFLOW (orig)); + /* Ensure constant sharing. */ + expr = build_int_cst_wide (TREE_TYPE (expr), + TREE_INT_CST_LOW (expr), + TREE_INT_CST_HIGH (expr)); + } + return expr; +} + +/* Fold away simple conversions, but make sure TREE_OVERFLOW is set + properly. */ tree cp_fold_convert (tree type, tree expr) { - return rvalue (fold_convert (type, expr)); + tree conv = fold_convert (type, expr); + conv = ignore_overflows (conv, expr); + return conv; } /* C++ conversions, preference to static cast conversions. */ @@ -661,6 +684,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (INTEGRAL_CODE_P (code)) { tree intype = TREE_TYPE (e); + tree converted; if (TREE_CODE (type) == ENUMERAL_TYPE) { @@ -705,7 +729,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (code == BOOLEAN_TYPE) return cp_truthvalue_conversion (e); - return fold_if_not_in_template (convert_to_integer (type, e)); + converted = fold_if_not_in_template (convert_to_integer (type, e)); + + /* Ignore any integer overflow caused by the conversion. */ + return ignore_overflows (converted, e); } if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e)) return nullptr_node; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index fb5ca7f..c372840 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11823,7 +11823,6 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc) if (TREE_CODE (value) == INTEGER_CST) { value = perform_integral_promotions (value); - constant_expression_warning (value); } else { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a805c6b..e00549e 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1054,7 +1054,6 @@ grokbitfield (const cp_declarator *declarator, if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width))) error ("width of bit-field %qD has non-integral type %qT", value, TREE_TYPE (width)); - constant_expression_warning (width); DECL_INITIAL (value) = width; SET_DECL_C_BIT_FIELD (value); } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 6f60c06..1560fc6 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2469,7 +2469,9 @@ location_of (tree t) else if (TREE_CODE (t) == OVERLOAD) t = OVL_FUNCTION (t); - return DECL_SOURCE_LOCATION (t); + if (DECL_P (t)) + return DECL_SOURCE_LOCATION (t); + return EXPR_LOC_OR_HERE (t); } /* Now the interfaces from error et al to dump_type et al. Each takes an diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fd7da34..494247e7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5789,7 +5789,7 @@ adjust_temp_type (tree type, tree temp) if (TREE_CODE (temp) == CONSTRUCTOR) return build_constructor (type, CONSTRUCTOR_ELTS (temp)); gcc_assert (SCALAR_TYPE_P (type)); - return fold_convert (type, temp); + return cp_fold_convert (type, temp); } /* Subroutine of cxx_eval_call_expression. @@ -6003,13 +6003,13 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, return result; } +/* FIXME speed this up, it's taking 16% of compile time on sieve testcase. */ + bool reduced_constant_expression_p (tree t) { - /* FIXME speed this up, it's taking 16% of compile time on sieve testcase. */ - if (cxx_dialect >= cxx0x && TREE_OVERFLOW_P (t)) - /* In C++0x, integer overflow makes this not a constant expression. - FIXME arithmetic overflow is different from conversion truncation */ + if (TREE_OVERFLOW_P (t)) + /* Integer overflow makes this not a constant expression. */ return false; /* FIXME are we calling this too much? */ return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE; @@ -6030,7 +6030,20 @@ verify_constant (tree t, bool allow_non_constant, bool *non_constant_p) if (!*non_constant_p && !reduced_constant_expression_p (t)) { if (!allow_non_constant) - error ("%qE is not a constant expression", t); + { + /* If T was already folded to a _CST with TREE_OVERFLOW set, + printing the folded constant isn't helpful. */ + if (TREE_OVERFLOW_P (t)) + { + permerror (input_location, "overflow in constant expression"); + /* If we're being permissive (and are in an enforcing + context), consider this constant. */ + if (flag_permissive) + return false; + } + else + error ("%q+E is not a constant expression", t); + } *non_constant_p = true; } return *non_constant_p; @@ -6895,12 +6908,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant) tree r = cxx_eval_constant_expression (NULL, t, allow_non_constant, false, &non_constant_p); - if (!non_constant_p && !reduced_constant_expression_p (r)) - { - if (!allow_non_constant) - error ("%qE is not a constant expression", t); - non_constant_p = true; - } + verify_constant (r, allow_non_constant, &non_constant_p); if (non_constant_p && !allow_non_constant) return error_mark_node; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6a52fc4..cad8817 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5717,33 +5717,6 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, allow_inverse_p, c_cast_p, complain); } -/* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return - a version of EXPR that has TREE_OVERFLOW set if it is set in ORIG. - Otherwise, return EXPR unchanged. */ - -static tree -ignore_overflows (tree expr, tree orig) -{ - if (TREE_CODE (expr) == INTEGER_CST - && CONSTANT_CLASS_P (orig) - && TREE_CODE (orig) != STRING_CST - && TREE_OVERFLOW (expr) != TREE_OVERFLOW (orig)) - { - if (!TREE_OVERFLOW (orig)) - /* Ensure constant sharing. */ - expr = build_int_cst_wide (TREE_TYPE (expr), - TREE_INT_CST_LOW (expr), - TREE_INT_CST_HIGH (expr)); - else - { - /* Avoid clobbering a shared constant. */ - expr = copy_node (expr); - TREE_OVERFLOW (expr) = TREE_OVERFLOW (orig); - } - } - return expr; -} - /* Perform a static_cast from EXPR to TYPE. When C_CAST_P is true, this static_cast is being attempted as one of the possible casts allowed by a C-style cast. (In that case, accessibility of base @@ -5757,7 +5730,6 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { tree intype; tree result; - tree orig; /* Assume the cast is valid. */ *valid_p = true; @@ -5814,8 +5786,14 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, expr = build_base_path (MINUS_EXPR, build_address (expr), base, /*nonnull=*/false); /* Convert the pointer to a reference -- but then remember that - there are no expressions with reference type in C++. */ - return convert_from_reference (cp_fold_convert (type, expr)); + there are no expressions with reference type in C++. + + We call rvalue so that there's an actual tree code + (NON_LVALUE_EXPR) for the static_cast; otherwise, if the operand + is a variable with the same type, the conversion would get folded + away, leaving just the variable and causing lvalue_kind to give + the wrong answer. */ + return convert_from_reference (rvalue (cp_fold_convert (type, expr))); } /* "An lvalue of type cv1 T1 can be cast to type rvalue reference to @@ -5830,8 +5808,6 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, return convert_from_reference (expr); } - orig = expr; - /* Resolve overloaded address here rather than once in implicit_conversion and again in the inverse code below. */ if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr)) @@ -5852,9 +5828,6 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { result = convert_from_reference (result); - /* Ignore any integer overflow caused by the cast. */ - result = ignore_overflows (result, orig); - /* [expr.static.cast] If T is a reference type, the result is an lvalue; otherwise, @@ -5894,13 +5867,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, || SCALAR_FLOAT_TYPE_P (type)) && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype))) - { - expr = ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); - - /* Ignore any integer overflow caused by the cast. */ - expr = ignore_overflows (expr, orig); - return expr; - } + return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL); if (TYPE_PTR_P (type) && TYPE_PTR_P (intype) && CLASS_TYPE_P (TREE_TYPE (type)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 74d974b..7d2688e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2010-11-08 Jason Merrill + + * g++.dg/expr/overflow1.C: New. + * g++.dg/warn/overflow-warn-1.C: Add expected diagnostics. + * g++.dg/warn/overflow-warn-3.C: Remove unnecessary line number. + * g++.dg/warn/overflow-warn-4.C: Add expected diagnostics. + * g++.dg/warn/overflow-warn-5.C: Don't expect wrong warning. + 2010-11-08 Rainer Orth * gcc.dg/pr35442.c: Adapt warning. diff --git a/gcc/testsuite/g++.dg/expr/overflow1.C b/gcc/testsuite/g++.dg/expr/overflow1.C new file mode 100644 index 0000000..b67b4e42 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/overflow1.C @@ -0,0 +1,8 @@ +#include + +enum E { + A = (unsigned char)-1, /* OK */ + B = (signed char)UCHAR_MAX, /* implementation-defined */ + C = INT_MAX+1, /* undefined (C)/ill-formed (C++) { dg-message "" } */ + D = UINT_MAX+1 /* OK */ +}; diff --git a/gcc/testsuite/g++.dg/warn/overflow-warn-1.C b/gcc/testsuite/g++.dg/warn/overflow-warn-1.C index 17bd067..22c512a 100644 --- a/gcc/testsuite/g++.dg/warn/overflow-warn-1.C +++ b/gcc/testsuite/g++.dg/warn/overflow-warn-1.C @@ -1,7 +1,7 @@ /* Test for diagnostics for constant overflow. */ /* Origin: Joseph Myers */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-fpermissive" } */ #include @@ -19,8 +19,10 @@ enum e { E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */ /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */ E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ + /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 21 } */ /* Again, overflow in evaluated subexpression. */ E6 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ + /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 24 } */ /* A cast does not constitute overflow in conversion. */ E7 = (char) INT_MAX }; @@ -29,6 +31,7 @@ struct s { int a; int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ + /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 33 } */ }; void @@ -49,10 +52,10 @@ void *n = 0; constants. The third has the overflow in an unevaluated subexpression, so is a null pointer constant. */ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ -/* { dg-error "invalid conversion from 'int' to 'void" "null" { target *-*-* } 51 } */ +/* { dg-warning "invalid conversion from 'int' to 'void" "null" { target *-*-* } 54 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 53 } */ -void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } 55 } */ +/* { dg-error "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 56 } */ +void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } } */ void g (int i) @@ -62,6 +65,7 @@ g (int i) case 0 * (1/0): /* { dg-warning "division by zero" } */ ; case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ + /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 67 } */ ; } } diff --git a/gcc/testsuite/g++.dg/warn/overflow-warn-3.C b/gcc/testsuite/g++.dg/warn/overflow-warn-3.C index ce03a97..d88c87a 100644 --- a/gcc/testsuite/g++.dg/warn/overflow-warn-3.C +++ b/gcc/testsuite/g++.dg/warn/overflow-warn-3.C @@ -57,7 +57,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ /* { dg-warning "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 58 } */ -void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } 60 } */ +void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } } */ void g (int i) diff --git a/gcc/testsuite/g++.dg/warn/overflow-warn-4.C b/gcc/testsuite/g++.dg/warn/overflow-warn-4.C index 0c916d0..374d2942 100644 --- a/gcc/testsuite/g++.dg/warn/overflow-warn-4.C +++ b/gcc/testsuite/g++.dg/warn/overflow-warn-4.C @@ -11,7 +11,7 @@ enum e { E1 = UINT_MAX + 1, /* Overflow in an unevaluated part of an expression is OK (example in the standard). */ - E2 = 2 || 1 / 0, /* { dg-bogus "warning: division by zero" "" { xfail *-*-* } 14 } */ + E2 = 2 || 1 / 0, /* { dg-bogus "warning: division by zero" "" { xfail *-*-* } } */ E3 = 1 / 0, /* { dg-warning "division by zero" } */ /* { dg-error "enumerator value for 'E3' is not an integer constant|not a constant expression" "enum error" { target *-*-* } 15 } */ /* But as in DR#031, the 1/0 in an evaluated subexpression means the @@ -20,9 +20,11 @@ enum e { /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */ E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */ /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */ + /* { dg-error "enumerator value for 'E5' is not an integer constant" "enum error" { target *-*-* } 21 } */ /* Again, overflow in evaluated subexpression. */ E6 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */ - /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 24 } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 25 } */ + /* { dg-error "enumerator value for 'E6' is not an integer constant" "enum error" { target *-*-* } 25 } */ /* A cast does not constitute overflow in conversion. */ E7 = (char) INT_MAX }; @@ -31,7 +33,8 @@ struct s { int a; int : 0 * (1 / 0); /* { dg-warning "division by zero" } */ int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ - /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 33 } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 35 } */ + /* { dg-error "bit-field .* width not an integer constant" "" { target *-*-* } 35 } */ }; void @@ -53,11 +56,11 @@ void *n = 0; constants. The third has the overflow in an unevaluated subexpression, so is a null pointer constant. */ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ -/* { dg-error "invalid conversion from 'int' to 'void" "null" { target *-*-* } 55 } */ +/* { dg-error "invalid conversion from 'int' to 'void" "null" { target *-*-* } 58 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 58 } */ -void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } 60 } */ +/* { dg-error "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 61 } */ +void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } } */ void g (int i) @@ -67,7 +70,7 @@ g (int i) case 0 * (1/0): /* { dg-warning "division by zero" } */ ; case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */ - /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 69 } */ + /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 72 } */ ; } } diff --git a/gcc/testsuite/g++.dg/warn/overflow-warn-5.C b/gcc/testsuite/g++.dg/warn/overflow-warn-5.C index 472d4a7..bdfec4a 100644 --- a/gcc/testsuite/g++.dg/warn/overflow-warn-5.C +++ b/gcc/testsuite/g++.dg/warn/overflow-warn-5.C @@ -1,7 +1,11 @@ /* PR c/27273 */ /* { dg-do compile } */ -/* { dg-options "-Woverflow" } */ + +// This used to warn about "overflow in implicit constant conversion", +// which was wrong; 512 is never converted to unsigned char. Rather, an +// appropriate warning would be that the & expression always evaluates to 0 +// because of the limited range of unsigned char. unsigned char rx_async(unsigned char p) { - return p & 512; /* { dg-warning "overflow in implicit constant conversion" } */ + return p & 512; /* { dg-warning "" "" { xfail *-*-* } } */ } diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4a5d630..d49f970 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2010-11-08 Jason Merrill + + * testsuite/20_util/ratio/cons/cons_overflow_neg.cc: Adjust + expected error. + 2010-11-08 Benjamin Kosnik * include/std/complex (operator==, !=): Mark constexpr. diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc index fa4c85e..e7f448d 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc @@ -52,6 +52,6 @@ test04() // { dg-error "denominator cannot be zero" "" { target *-*-* } 153 } // { dg-error "out of range" "" { target *-*-* } 154 } // { dg-error "non-constant expression" "" { target *-*-* } 59 } -// { dg-error "is not a constant expression" "" { target *-*-* } 59 } +// { dg-error "overflow in constant expression" "" { target *-*-* } 59 } // { dg-error "not a member" "" { target *-*-* } 162 } // { dg-error "not a valid template argument" "" { target *-*-* } 164 } -- 2.7.4