diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-16 11:04:09 +0000 |
---|---|---|
committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-16 11:04:09 +0000 |
commit | 13f0eb203f1c4d5cfb52f559ab84725160d89f2e (patch) | |
tree | a82d5b1b25a2b0a52f0c9e6f96bfb4fbbb2d9e1c /gcc/cp/init.c | |
parent | 0f2bc8a91019330220f928f3709c06a684b9606c (diff) | |
download | gcc-13f0eb203f1c4d5cfb52f559ab84725160d89f2e.tar.gz |
cp:
PR c++/18905
* cp-tree.h (integral_constant_value): Declare.
* call.c (null_ptr_cst_p): Use integral_constant_value, not
decl_constant_value.
(convert_like_real): Likewise.
* class.c (check_bitfield_decl): Likewise.
* cvt.c (ocp_convert): Likewise.
(convert): Remove unnecessary decl_constant_value call.
* decl.c (compute_array_index_type): Use integral_constant_value,
not decl_constant_value.
(build_enumerator): Likewise.
* decl2.c (grokfield): Likewise.
* init.c (decl_constant_value): Simplify.
(integral_constant_value): New.
* pt.c (fold_decl_constant_value): Use integral_constant_value,
remove subsequent check.
(tsubst): Use integral_constant_value, not decl_constant_value.
(tsubst_copy, unify): Likewise.
* typeck.c (decay_conversion): Likewise.
(build_compound_expr): Remove unnecessary decl_constant_value
calls.
(build_static_cast_1, build_reinterpret_cast_1):
(convert_for_assignment): Remove comment about not calling
decl_constant_value.
testsuite:
PR c++/18905
* g++.dg/template/init4.C: New.
* g++.dg/opt/static3.C: Enable optimizer.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92257 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index a1a404c53f9..90b84eb6a45 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1558,46 +1558,48 @@ build_offset_ref (tree type, tree name, bool address_p) return member; } -/* If DECL is a `const' declaration, and its value is a known - constant, then return that value. */ +/* 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. */ tree -decl_constant_value (tree decl) +integral_constant_value (tree decl) { - /* When we build a COND_EXPR, we don't know whether it will be used - as an lvalue or as an rvalue. If it is an lvalue, it's not safe - to replace the second and third operands with their - initializers. So, we do that here. */ - if (TREE_CODE (decl) == COND_EXPR) - { - tree d1; - tree d2; - - d1 = decl_constant_value (TREE_OPERAND (decl, 1)); - d2 = decl_constant_value (TREE_OPERAND (decl, 2)); + 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_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))) + && DECL_INITIAL (decl) + && DECL_INITIAL (decl) != error_mark_node + && TREE_TYPE (DECL_INITIAL (decl)) + && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))) + return DECL_INITIAL (decl); + return decl; +} - if (d1 != TREE_OPERAND (decl, 1) || d2 != TREE_OPERAND (decl, 2)) - return build3 (COND_EXPR, - TREE_TYPE (decl), - TREE_OPERAND (decl, 0), d1, d2); - } +/* 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_P (decl) - && (/* Enumeration constants are constant. */ - TREE_CODE (decl) == CONST_DECL +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))) - && TREE_CODE (decl) != PARM_DECL + 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)) - /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) + /* 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; } |