summaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-16 11:04:09 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-16 11:04:09 +0000
commit13f0eb203f1c4d5cfb52f559ab84725160d89f2e (patch)
treea82d5b1b25a2b0a52f0c9e6f96bfb4fbbb2d9e1c /gcc/cp/init.c
parent0f2bc8a91019330220f928f3709c06a684b9606c (diff)
downloadgcc-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.c64
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;
}