summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/tree.c')
-rw-r--r--contrib/gcc/cp/tree.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c
index d353b06..d703b8a 100644
--- a/contrib/gcc/cp/tree.c
+++ b/contrib/gcc/cp/tree.c
@@ -464,7 +464,12 @@ build_cplus_array_type_1 (elt_type, index_type)
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- if (processing_template_decl
+ /* Don't do the minimal thing just because processing_template_decl is
+ set; we want to give string constants the right type immediately, so
+ we don't have to fix them up at instantiation time. */
+ if ((processing_template_decl
+ && index_type && TYPE_MAX_VALUE (index_type)
+ && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST)
|| uses_template_parms (elt_type)
|| uses_template_parms (index_type))
{
@@ -505,18 +510,32 @@ build_cplus_array_type (elt_type, index_type)
/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles
arrays correctly. In particular, if TYPE is an array of T's, and
- TYPE_QUALS is non-empty, returns an array of qualified T's. If
- at attempt is made to qualify a type illegally, and COMPLAIN is
- non-zero, an error is issued. If COMPLAIN is zero, error_mark_node
- is returned. */
-
+ TYPE_QUALS is non-empty, returns an array of qualified T's.
+
+ FLAGS determines how to deal with illformed qualifications. If
+ tf_ignore_bad_quals is set, then bad qualifications are dropped
+ (this is permitted if TYPE was introduced via a typedef or template
+ type parameter). If bad qualifications are dropped and tf_warning
+ is set, then a warning is issued for non-const qualifications. If
+ tf_ignore_bad_quals is not set and tf_error is not set, we
+ return error_mark_node. Otherwise, we issue an error, and ignore
+ the qualifications.
+
+ Qualification of a reference type is valid when the reference came
+ via a typedef or template type argument. [dcl.ref] No such
+ dispensation is provided for qualifying a function type. [dcl.fct]
+ DR 295 queries this and the proposed resolution brings it into line
+ with qualifiying a reference. We implement the DR. We also behave
+ in a similar manner for restricting non-pointer types. */
+
tree
cp_build_qualified_type_real (type, type_quals, complain)
tree type;
int type_quals;
- int complain;
+ tsubst_flags_t complain;
{
tree result;
+ int bad_quals = TYPE_UNQUALIFIED;
if (type == error_mark_node)
return type;
@@ -524,32 +543,51 @@ cp_build_qualified_type_real (type, type_quals, complain)
if (type_quals == cp_type_quals (type))
return type;
- /* A restrict-qualified pointer type must be a pointer (or reference)
+ /* A reference, fucntion or method type shall not be cv qualified.
+ [dcl.ref], [dct.fct] */
+ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ {
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ }
+
+ /* A restrict-qualified type must be a pointer (or reference)
to object or incomplete type. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& TREE_CODE (type) != TEMPLATE_TYPE_PARM
- && (!POINTER_TYPE_P (type)
- || TYPE_PTRMEM_P (type)
- || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
+ && TREE_CODE (type) != TYPENAME_TYPE
+ && !POINTER_TYPE_P (type))
{
- if (complain)
- error ("`%T' cannot be `restrict'-qualified", type);
- else
- return error_mark_node;
-
+ bad_quals |= TYPE_QUAL_RESTRICT;
type_quals &= ~TYPE_QUAL_RESTRICT;
}
- if (type_quals != TYPE_UNQUALIFIED
- && TREE_CODE (type) == FUNCTION_TYPE)
+ if (bad_quals == TYPE_UNQUALIFIED)
+ /*OK*/;
+ else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+ return error_mark_node;
+ else
{
- if (complain)
- error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type);
- else
- return error_mark_node;
- type_quals = TYPE_UNQUALIFIED;
+ if (complain & tf_ignore_bad_quals)
+ /* We're not going to warn about constifying things that can't
+ be constified. */
+ bad_quals &= ~TYPE_QUAL_CONST;
+ if (bad_quals)
+ {
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+
+ if (!(complain & tf_ignore_bad_quals))
+ error ("`%V' qualifiers cannot be applied to `%T'",
+ bad_type, type);
+ else if (complain & tf_warning)
+ warning ("ignoring `%V' qualifiers on `%T'", bad_type, type);
+ }
}
- else if (TREE_CODE (type) == ARRAY_TYPE)
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
{
/* In C++, the qualification really applies to the array element
type. Obtain the appropriately qualified element type. */
@@ -591,7 +629,7 @@ cp_build_qualified_type_real (type, type_quals, complain)
{
/* For a pointer-to-member type, we can't just return a
cv-qualified version of the RECORD_TYPE. If we do, we
- haven't change the field that contains the actual pointer to
+ haven't changed the field that contains the actual pointer to
a method, and so TYPE_PTRMEMFUNC_FN_TYPE will be wrong. */
tree t;
@@ -599,7 +637,7 @@ cp_build_qualified_type_real (type, type_quals, complain)
t = cp_build_qualified_type_real (t, type_quals, complain);
return build_ptrmemfunc_type (t);
}
-
+
/* Retrieve (or create) the appropriately qualified variant. */
result = build_qualified_type (type, type_quals);
@@ -999,7 +1037,6 @@ cp_statement_code_p (code)
switch (code)
{
case SUBOBJECT:
- case CLEANUP_STMT:
case CTOR_STMT:
case CTOR_INITIALIZER:
case RETURN_INIT:
@@ -2100,6 +2137,10 @@ cp_cannot_inline_tree_fn (fnp)
{
tree fn = *fnp;
+ if (flag_really_no_inline
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
+ return 1;
+
/* We can inline a template instantiation only if it's fully
instantiated. */
if (DECL_TEMPLATE_INFO (fn)
OpenPOWER on IntegriCloud