diff options
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 168 |
1 files changed, 112 insertions, 56 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9be5adf4af3..d767125ad10 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1913,7 +1913,8 @@ redeclaration_error_message (tree newdecl, tree olddecl) /* If this is a pure function, its olddecl will actually be the original initialization to `0' (which we force to call abort()). Don't complain about redefinition in this case. */ - if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl)) + if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl) + && DECL_INITIAL (olddecl) == NULL_TREE) return 0; /* If both functions come from different namespaces, this is not @@ -4175,6 +4176,7 @@ reshape_init (tree type, tree *initp) tree old_init_value; tree new_init; bool brace_enclosed_p; + bool string_init_p; old_init = *initp; old_init_value = (TREE_CODE (*initp) == TREE_LIST @@ -4238,6 +4240,7 @@ reshape_init (tree type, tree *initp) return old_init; } + string_init_p = false; if (TREE_CODE (old_init_value) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))) @@ -4252,6 +4255,7 @@ reshape_init (tree type, tree *initp) /* Move past the initializer. */ *initp = TREE_CHAIN (old_init); TREE_CHAIN (old_init) = NULL_TREE; + string_init_p = true; } else { @@ -4352,10 +4356,15 @@ reshape_init (tree type, tree *initp) new_init = build_tree_list (TREE_PURPOSE (old_init), new_init); } - /* If this was a brace-enclosed initializer and all of the - initializers were not used up, there is a problem. */ - if (brace_enclosed_p && *initp) - error ("too many initializers for %qT", type); + /* If there are more initializers than necessary, issue a + diagnostic. */ + if (*initp) + { + if (brace_enclosed_p) + error ("too many initializers for %qT", type); + else if (warn_missing_braces && !string_init_p) + warning ("missing braces around initializer"); + } return new_init; } @@ -4743,9 +4752,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (type == error_mark_node) goto finish_end; - if (TYPE_HAS_MUTABLE_P (type)) - TREE_READONLY (decl) = 0; - if (processing_template_decl) { /* Add this declaration to the statement-tree. */ @@ -4792,16 +4798,13 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ttype = target_type (type); - /* Currently, GNU C++ puts constants in text space, making them - impossible to initialize. In the future, one would hope for - an operating system which understood the difference between - initialization and the running of a program. */ - if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)) + /* A reference will be modified here, as it is initialized. */ + if (! DECL_EXTERNAL (decl) + && TREE_READONLY (decl) + && TREE_CODE (type) == REFERENCE_TYPE) { was_readonly = 1; - if (TYPE_NEEDS_CONSTRUCTING (type) - || TREE_CODE (type) == REFERENCE_TYPE) - TREE_READONLY (decl) = 0; + TREE_READONLY (decl) = 0; } if (TREE_CODE (decl) == VAR_DECL) @@ -5924,8 +5927,7 @@ grokvardecl (tree type, declare an entity with linkage. Only check this for public decls for now. */ - tree t1 = TREE_TYPE (decl); - tree t = no_linkage_check (t1, /*relaxed_p=*/false); + tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false); if (t) { if (TYPE_ANONYMOUS_P (t)) @@ -5933,31 +5935,26 @@ grokvardecl (tree type, if (DECL_EXTERN_C_P (decl)) /* Allow this; it's pretty common in C. */ ; - else if (same_type_ignoring_top_level_qualifiers_p(t1, t)) - /* This is something like "enum { a = 3 } x;", which is - well formed. The enum doesn't have "a name with no - linkage", because it has no name. See closed CWG issue - 132. - - Note that while this construct is well formed in C++03 - it is likely to become ill formed in C++0x. See open - CWG issue 389 and related issues. */ - ; else { - /* It's a typedef referring to an anonymous type. */ - pedwarn ("non-local variable %q#D uses anonymous type", + /* DRs 132, 319 and 389 seem to indicate types with + no linkage can only be used to declare extern "C" + entities. Since it's not always an error in the + ISO C++ 90 Standard, we only issue a warning. */ + warning ("non-local variable %q#D uses anonymous type", decl); if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) - cp_pedwarn_at ("%q#D does not refer to the unqualified " - "type, so it is not used for linkage", + cp_warning_at ("%q#D does not refer to the unqualified " + "type, so it is not used for linkage", TYPE_NAME (t)); } } else - pedwarn ("non-local variable %q#D uses local type %qT", decl, t); + warning ("non-local variable %q#D uses local type %qT", decl, t); } } + else + DECL_INTERFACE_KNOWN (decl) = 1; return decl; } @@ -6553,9 +6550,22 @@ grokdeclarator (const cp_declarator *declarator, { case BIT_NOT_EXPR: { - tree type = TREE_OPERAND (decl, 0); - type = constructor_name (type); - name = IDENTIFIER_POINTER (type); + tree type; + + if (innermost_code != cdk_function) + { + error ("declaration of %qD as non-function", decl); + return error_mark_node; + } + else if (!qualifying_scope + && !(current_class_type && at_class_scope_p ())) + { + error ("declaration of %qD as non-member", decl); + return error_mark_node; + } + + type = TREE_OPERAND (decl, 0); + name = IDENTIFIER_POINTER (constructor_name (type)); } break; @@ -6912,6 +6922,20 @@ grokdeclarator (const cp_declarator *declarator, error ("qualifiers are not allowed on declaration of %<operator %T%>", ctor_return_type); + if (TREE_CODE (type) == FUNCTION_TYPE + && type_quals != TYPE_UNQUALIFIED) + { + /* This was an error in C++98 (cv-qualifiers cannot be added to + a function type), but DR 295 makes the code well-formed by + dropping the extra qualifiers. */ + if (pedantic) + { + tree bad_type = build_qualified_type (type, type_quals); + pedwarn ("ignoring %qV qualifiers added to function type %qT", + bad_type, type); + } + type_quals = TYPE_UNQUALIFIED; + } type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) @@ -7273,6 +7297,7 @@ grokdeclarator (const cp_declarator *declarator, } type = build_function_type (type, arg_types); + type = cp_build_qualified_type (type, quals); } break; @@ -7305,7 +7330,15 @@ grokdeclarator (const cp_declarator *declarator, && (TREE_CODE (type) == FUNCTION_TYPE || (quals && TREE_CODE (type) == METHOD_TYPE))) { - tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); + tree dummy; + + /* If the type is a FUNCTION_TYPE, pick up the + qualifiers from that function type. No other + qualifiers may be supplied. */ + if (TREE_CODE (type) == FUNCTION_TYPE) + quals = cp_type_quals (type); + + dummy = build_decl (TYPE_DECL, NULL_TREE, type); grok_method_quals (declarator->u.pointer.class_type, dummy, quals); type = TREE_TYPE (dummy); @@ -7329,6 +7362,9 @@ grokdeclarator (const cp_declarator *declarator, declarator->u.pointer.class_type); type = build_pointer_type (type); } + else if (declarator->u.pointer.class_type == error_mark_node) + /* We will already have complained. */ + type = error_mark_node; else type = build_ptrmem_type (declarator->u.pointer.class_type, type); @@ -7599,11 +7635,12 @@ grokdeclarator (const cp_declarator *declarator, { if (ctype == NULL_TREE) { - if (TREE_CODE (type) != METHOD_TYPE) - error ("%Jinvalid type qualifier for non-member function type", - decl); - else + if (TREE_CODE (type) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (type); + /* Any qualifiers on a function type typedef have + already been dealt with. */ + else if (TREE_CODE (type) == FUNCTION_TYPE) + quals = TYPE_UNQUALIFIED; } if (ctype != NULL_TREE) grok_method_quals (ctype, decl, quals); @@ -7646,6 +7683,23 @@ grokdeclarator (const cp_declarator *declarator, } parms = nreverse (decls); + + if (decl_context != TYPENAME) + { + /* A cv-qualifier-seq shall only be part of the function type + for a non-static member function. [8.3.5/4 dcl.fct] */ + if (cp_type_quals (type) != TYPE_UNQUALIFIED + && (current_class_type == NULL_TREE || staticp) ) + { + error ("qualified function types cannot be used to declare %s functions", + (staticp? "static member" : "free")); + type = TYPE_MAIN_VARIANT (type); + } + + /* The qualifiers on the function type become the qualifiers on + the non-static member function. */ + quals |= cp_type_quals (type); + } } /* If this is a type name (such as, in a cast or sizeof), @@ -7803,15 +7857,6 @@ grokdeclarator (const cp_declarator *declarator, int publicp = 0; tree function_context; - /* We catch the others as conflicts with the builtin - typedefs. */ - if (friendp && unqualified_id == ridpointers[(int) RID_SIGNED]) - { - error ("function %qD cannot be declared friend", - unqualified_id); - friendp = 0; - } - if (friendp == 0) { if (ctype == NULL_TREE) @@ -7849,6 +7894,18 @@ grokdeclarator (const cp_declarator *declarator, TYPE_ARG_TYPES (type)); } + /* Check that the name used for a destructor makes sense. */ + if (sfk == sfk_destructor + && !same_type_p (TREE_OPERAND + (id_declarator->u.id.unqualified_name, 0), + ctype)) + { + error ("declaration of %qD as member of %qT", + id_declarator->u.id.unqualified_name, + ctype); + return error_mark_node; + } + /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ function_context = (ctype != NULL_TREE) ? decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE; @@ -8178,7 +8235,7 @@ grokdeclarator (const cp_declarator *declarator, when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ if (!processing_template_decl) - c_apply_type_quals_to_decl (type_quals, decl); + cp_apply_type_quals_to_decl (type_quals, decl); return decl; } @@ -9962,7 +10019,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_IGNORED_P (resdecl) = 1; DECL_RESULT (decl1) = resdecl; - c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); + cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl); } /* Initialize RTL machinery. We cannot do this until @@ -10885,9 +10942,11 @@ complete_vars (tree type) if (same_type_p (type, TREE_PURPOSE (*list))) { tree var = TREE_VALUE (*list); + tree type = TREE_TYPE (var); /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ - complete_type (TREE_TYPE (var)); + complete_type (type); + cp_apply_type_quals_to_decl (cp_type_quals (type), var); /* Remove this entry from the list. */ *list = TREE_CHAIN (*list); } @@ -10929,9 +10988,6 @@ cxx_maybe_build_cleanup (tree decl) rval = build_delete (TREE_TYPE (rval), rval, sfk_complete_destructor, flags, 0); - if (has_vbases && !TYPE_HAS_DESTRUCTOR (type)) - rval = build_compound_expr (rval, build_vbase_delete (type, decl)); - return rval; } return NULL_TREE; |