@@ -101,12 +101,54 @@ struct constexpr_global_ctx
101
101
auto_vec<tree, 16 > heap_vars;
102
102
/* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */
103
103
vec<tree> *cleanups;
104
+ /* If non-null, only allow modification of existing values of the variables
105
+ in this set. Set by modifiable_tracker, below. */
106
+ hash_set<tree> *modifiable;
104
107
/* Number of heap VAR_DECL deallocations. */
105
108
unsigned heap_dealloc_count;
106
109
/* Constructor. */
107
110
constexpr_global_ctx ()
108
111
: constexpr_ops_count (0 ), cleanups (NULL ), heap_dealloc_count (0 )
109
112
{}
113
+
114
+ tree get_value (tree t)
115
+ {
116
+ if (tree *p = values.get (t))
117
+ if (*p != void_node)
118
+ return *p;
119
+ return NULL_TREE;
120
+ }
121
+ tree *get_value_ptr (tree t, bool initializing)
122
+ {
123
+ if (modifiable && !modifiable->contains (t))
124
+ return nullptr ;
125
+ if (tree *p = values.get (t))
126
+ {
127
+ if (*p != void_node)
128
+ return p;
129
+ else if (initializing)
130
+ {
131
+ *p = NULL_TREE;
132
+ return p;
133
+ }
134
+ }
135
+ return nullptr ;
136
+ }
137
+ void put_value (tree t, tree v)
138
+ {
139
+ bool already_in_map = values.put (t, v);
140
+ if (!already_in_map && modifiable)
141
+ modifiable->add (t);
142
+ }
143
+ void destroy_value (tree t)
144
+ {
145
+ if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL
146
+ || TREE_CODE (t) == RESULT_DECL)
147
+ values.put (t, void_node);
148
+ else
149
+ values.remove (t);
150
+ }
151
+ void clear_value (tree t) { values.remove (t); }
110
152
};
111
153
112
154
/* In constexpr.cc */
@@ -457,6 +499,7 @@ save_fundef_copy (tree fun, tree copy)
457
499
458
500
static tree constant_value_1 (tree decl, bool strict_p,
459
501
bool return_aggregate_cst_ok_p, bool unshare_p);
502
+ static tree decl_really_constant_value (tree decl, bool unshare_p /* = true*/ );
460
503
tree decl_constant_value (tree decl, bool unshare_p);
461
504
462
505
static void non_const_var_error (location_t loc, tree r);
@@ -1925,30 +1968,40 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
1925
1968
}
1926
1969
/* fall through */
1927
1970
case CONST_DECL:
1928
- {
1929
- /* We used to not check lval for CONST_DECL, but darwin.cc uses
1930
- CONST_DECL for aggregate constants. */
1931
- if (lval)
1932
- return t;
1933
- else if (t == ctx->object )
1934
- return ctx->ctor ;
1935
- if (VAR_P (t))
1936
- if (tree *p = ctx->global ->values .get (t))
1937
- if (*p != NULL_TREE)
1938
- {
1939
- r = *p;
1940
- break ;
1941
- }
1971
+ /* We used to not check lval for CONST_DECL, but darwin.cc uses
1972
+ CONST_DECL for aggregate constants. */
1973
+ if (lval)
1974
+ return t;
1975
+ else if (t == ctx->object )
1976
+ return ctx->ctor ;
1977
+ if (VAR_P (t))
1978
+ {
1979
+ if (tree v = ctx->global ->get_value (t))
1980
+ {
1981
+ r = v;
1982
+ break ;
1983
+ }
1984
+ }
1985
+ if (COMPLETE_TYPE_P (TREE_TYPE (t))
1986
+ && is_really_empty_class (TREE_TYPE (t), /* ignore_vptr*/ false ))
1987
+ {
1988
+ /* If the class is empty, we aren't actually loading anything. */
1989
+ r = build_constructor (TREE_TYPE (t), NULL );
1990
+ TREE_CONSTANT (r) = true ;
1991
+ }
1992
+ else if (ctx->strict )
1993
+ r = decl_really_constant_value (t, /* unshare_p=*/ false );
1994
+ else
1942
1995
r = decl_constant_value (t, /* unshare_p=*/ false );
1943
- if (TREE_CODE (r) == TARGET_EXPR
1944
- && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
1945
- r = TARGET_EXPR_INITIAL (r);
1946
- if (DECL_P (r))
1947
- {
1996
+ if (TREE_CODE (r) == TARGET_EXPR
1997
+ && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
1998
+ r = TARGET_EXPR_INITIAL (r);
1999
+ if (DECL_P (r) && !(VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
2000
+ {
2001
+ if (!ctx->quiet )
1948
2002
non_const_var_error (loc, r);
1949
- return r;
1950
- }
1951
- }
2003
+ *non_constant_p = true ;
2004
+ }
1952
2005
break ;
1953
2006
1954
2007
case PARM_DECL:
@@ -4024,6 +4077,17 @@ constant_value_1 (tree decl, bool, bool, bool unshare_p)
4024
4077
return unshare_p ? unshare_expr (decl) : decl;
4025
4078
}
4026
4079
4080
+ /* Like scalar_constant_value, but can also return aggregate initializers.
4081
+ If UNSHARE_P, return an unshared copy of the initializer. */
4082
+
4083
+ tree
4084
+ decl_really_constant_value (tree decl, bool unshare_p /* = true*/ )
4085
+ {
4086
+ return constant_value_1 (decl, /* strict_p=*/ true ,
4087
+ /* return_aggregate_cst_ok_p=*/ true ,
4088
+ /* unshare_p=*/ unshare_p);
4089
+ }
4090
+
4027
4091
// A more relaxed version of decl_really_constant_value, used by the
4028
4092
// common C/C++ code.
4029
4093
tree
@@ -4037,15 +4101,38 @@ decl_constant_value (tree decl, bool unshare_p)
4037
4101
static void
4038
4102
non_const_var_error (location_t loc, tree r)
4039
4103
{
4040
- error_at (loc,
4041
- " the value of %qD is not usable in a constant "
4042
- " expression" ,
4043
- r);
4104
+ tree type = TREE_TYPE (r);
4105
+
4044
4106
/* Avoid error cascade. */
4045
4107
if (DECL_INITIAL (r) == error_mark_node)
4046
4108
return ;
4047
-
4048
- // more in cp/constexpr.cc
4109
+ if (DECL_DECLARED_CONSTEXPR_P (r))
4110
+ inform (DECL_SOURCE_LOCATION (r), " %qD used in its own initializer" , r);
4111
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
4112
+ {
4113
+ if (!DECL_INITIAL (r) || !TREE_CONSTANT (DECL_INITIAL (r))
4114
+ || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
4115
+ inform (DECL_SOURCE_LOCATION (r),
4116
+ " %qD was not initialized with a constant "
4117
+ " expression" ,
4118
+ r);
4119
+ else
4120
+ gcc_unreachable ();
4121
+ }
4122
+ else if (TYPE_REF_P (type))
4123
+ inform (DECL_SOURCE_LOCATION (r),
4124
+ " %qD was not initialized with a constant "
4125
+ " expression" ,
4126
+ r);
4127
+ else
4128
+ {
4129
+ if (!DECL_DECLARED_CONSTEXPR_P (r))
4130
+ inform (DECL_SOURCE_LOCATION (r), " %qD was not declared %<constexpr%>" ,
4131
+ r);
4132
+ else
4133
+ inform (DECL_SOURCE_LOCATION (r),
4134
+ " %qD does not have integral or enumeration type" , r);
4135
+ }
4049
4136
}
4050
4137
4051
4138
static tree
0 commit comments