mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-06 09:29:51 +08:00
re PR c++/21089 (C++ front-end does not "inline" the static const double)
PR c++/21089 * call.c (convert_like_real): Use decl_constant_value, not integral_constant_value. * init.c (constant_value_1): New function. (integral_constant_value): Use it. (decl_constant_value): Likewise. * typeck.c (decay_conversion): Use decl_constant_value, not integral_constant_value. PR c++/21089 * g++.dg/init/float1.C: New test. From-SVN: r105256
This commit is contained in:
parent
8f4c0ef6a4
commit
393e756da7
@ -1,5 +1,14 @@
|
||||
2005-10-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/21089
|
||||
* call.c (convert_like_real): Use decl_constant_value, not
|
||||
integral_constant_value.
|
||||
* init.c (constant_value_1): New function.
|
||||
(integral_constant_value): Use it.
|
||||
(decl_constant_value): Likewise.
|
||||
* typeck.c (decay_conversion): Use decl_constant_value, not
|
||||
integral_constant_value.
|
||||
|
||||
PR c++/21369
|
||||
* parser.c (cp_parser_elaborated_type_specifier): Don't treat
|
||||
class types as templates if the type is not appearing as part of a
|
||||
|
@ -4298,7 +4298,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
||||
about to bind it to a reference, in which case we need to
|
||||
leave it as an lvalue. */
|
||||
if (inner >= 0)
|
||||
expr = integral_constant_value (expr);
|
||||
expr = decl_constant_value (expr);
|
||||
if (convs->check_copy_constructor_p)
|
||||
check_constructor_callable (totype, expr);
|
||||
return expr;
|
||||
|
@ -1559,16 +1559,20 @@ build_offset_ref (tree type, tree name, bool address_p)
|
||||
return member;
|
||||
}
|
||||
|
||||
/* If DECL is a CONST_DECL, or a constant VAR_DECL initialized by
|
||||
constant of integral or enumeration type, then return that value.
|
||||
These are those variables permitted in constant expressions by
|
||||
[5.19/1]. FIXME:If we did lazy folding, this could be localized. */
|
||||
/* If DECL is a scalar enumeration constant or variable with a
|
||||
constant initializer, return the initializer (or, its initializers,
|
||||
recursively); otherwise, return DECL. If INTEGRAL_P, the
|
||||
initializer is only returned if DECL is an integral
|
||||
constant-expression. */
|
||||
|
||||
tree
|
||||
integral_constant_value (tree decl)
|
||||
static tree
|
||||
constant_value_1 (tree decl, bool integral_p)
|
||||
{
|
||||
while (TREE_CODE (decl) == CONST_DECL
|
||||
|| DECL_INTEGRAL_CONSTANT_VAR_P (decl))
|
||||
|| (integral_p
|
||||
? DECL_INTEGRAL_CONSTANT_VAR_P (decl)
|
||||
: (TREE_CODE (decl) == VAR_DECL
|
||||
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
|
||||
{
|
||||
tree init;
|
||||
/* If DECL is a static data member in a template class, we must
|
||||
@ -1583,34 +1587,42 @@ integral_constant_value (tree decl)
|
||||
init = fold_non_dependent_expr (init);
|
||||
if (!(init || init == error_mark_node)
|
||||
|| !TREE_TYPE (init)
|
||||
|| !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init)))
|
||||
|| (integral_p
|
||||
? !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init))
|
||||
: (!TREE_CONSTANT (init)
|
||||
/* Do not return an aggregate constant (of which
|
||||
string literals are a special case), as we do not
|
||||
want to make inadvertant copies of such entities,
|
||||
and we must be sure that their addresses are the
|
||||
same everywhere. */
|
||||
|| TREE_CODE (init) == CONSTRUCTOR
|
||||
|| TREE_CODE (init) == STRING_CST)))
|
||||
break;
|
||||
decl = init;
|
||||
}
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* A more relaxed version of integral_constant_value, for which type
|
||||
is not considered. This is used by the common C/C++ code, and not
|
||||
directly by the C++ front end. */
|
||||
/* If DECL is a CONST_DECL, or a constant VAR_DECL initialized by
|
||||
constant of integral or enumeration type, then return that value.
|
||||
These are those variables permitted in constant expressions by
|
||||
[5.19/1]. */
|
||||
|
||||
tree
|
||||
integral_constant_value (tree decl)
|
||||
{
|
||||
return constant_value_1 (decl, /*integral_p=*/true);
|
||||
}
|
||||
|
||||
/* A more relaxed version of integral_constant_value, used by the
|
||||
common C/C++ code and by the C++ front-end for optimization
|
||||
purposes. */
|
||||
|
||||
tree
|
||||
decl_constant_value (tree decl)
|
||||
{
|
||||
if ((TREE_CODE (decl) == CONST_DECL
|
||||
|| (TREE_CODE (decl) == VAR_DECL
|
||||
/* And so are variables with a 'const' type -- unless they
|
||||
are also 'volatile'. */
|
||||
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))
|
||||
&& DECL_INITIAL (decl)
|
||||
&& DECL_INITIAL (decl) != error_mark_node
|
||||
/* This is invalid if initial value is not constant. If it has
|
||||
either a function call, a memory reference, or a variable,
|
||||
then re-evaluating it could give different results. */
|
||||
&& TREE_CONSTANT (DECL_INITIAL (decl)))
|
||||
return DECL_INITIAL (decl);
|
||||
|
||||
return decl;
|
||||
return constant_value_1 (decl,
|
||||
/*integral_p=*/processing_template_decl);
|
||||
}
|
||||
|
||||
/* Common subroutines of build_new and build_vec_delete. */
|
||||
|
@ -1356,7 +1356,7 @@ decay_conversion (tree exp)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
exp = integral_constant_value (exp);
|
||||
exp = decl_constant_value (exp);
|
||||
|
||||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||
Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */
|
||||
|
@ -1,5 +1,8 @@
|
||||
2005-10-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/21089
|
||||
* g++.dg/init/float1.C: New test.
|
||||
|
||||
PR c++/24277
|
||||
* g++.dg/init/member1.C: Tweak error markers.
|
||||
|
||||
|
19
gcc/testsuite/g++.dg/init/float1.C
Normal file
19
gcc/testsuite/g++.dg/init/float1.C
Normal file
@ -0,0 +1,19 @@
|
||||
// PR c++/21089
|
||||
// { dg-do run }
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
static const double a = 1.0;
|
||||
struct S {
|
||||
S();
|
||||
};
|
||||
static S s;
|
||||
static const double b = a + 1.0;
|
||||
|
||||
S::S() {
|
||||
if (b < 1.9 || b > 2.1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int main () {
|
||||
}
|
Loading…
Reference in New Issue
Block a user