diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-common.c | 1 | ||||
-rw-r--r-- | gcc/c-common.h | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 19 | ||||
-rw-r--r-- | gcc/cp/decl.c | 86 | ||||
-rw-r--r-- | gcc/cp/parser.c | 9 | ||||
-rw-r--r-- | gcc/cp/pt.c | 26 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 81 | ||||
-rw-r--r-- | gcc/cp/tree.c | 3 | ||||
-rw-r--r-- | gcc/tree.h | 5 |
11 files changed, 232 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96536260f6e..e80433ae8b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-09-30 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * tree.h (tree_decl_common::lang_flag_8): New. + * c-common.c (c_common_reswords): Include "constexpr" as C++0x + keyword. + * c-common.h (RID_CONSTEXPR): New. + 2009-09-30 Uros Bizjak <ubizjak@gmail.com> * config/alpha/alpha.c (alpha_gimplify_va_arg_1): diff --git a/gcc/c-common.c b/gcc/c-common.c index baa3d35c27f..4de92d0de95 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -631,6 +631,7 @@ const struct c_common_resword c_common_reswords[] = { "char32_t", RID_CHAR32, D_CXXONLY | D_CXX0X | D_CXXWARN }, { "class", RID_CLASS, D_CXX_OBJC | D_CXXWARN }, { "const", RID_CONST, 0 }, + { "constexpr", RID_CONSTEXPR, D_CXXONLY | D_CXX0X | D_CXXWARN }, { "const_cast", RID_CONSTCAST, D_CXXONLY | D_CXXWARN }, { "continue", RID_CONTINUE, 0 }, { "decltype", RID_DECLTYPE, D_CXXONLY | D_CXX0X | D_CXXWARN }, diff --git a/gcc/c-common.h b/gcc/c-common.h index 6a02e046209..c1655ae69ff 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -114,7 +114,7 @@ enum rid RID_IS_UNION, /* C++0x */ - RID_STATIC_ASSERT, RID_DECLTYPE, + RID_STATIC_ASSERT, RID_CONSTEXPR, RID_DECLTYPE, /* Objective-C */ RID_AT_ENCODE, RID_AT_END, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f617fb1c887..a25f62b9a91 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2009-09-30 Gabriel Dos Reis <gdr@cs.tamu.edu> + + * decl.c (check_for_uninitialized_const_var): Check constexpr + variables too. + (build_ptrmemfunc_type): Make the result a literal type. + (build_ptrmem_type): Likewise. + (grokdeclarator): Handle `constexpr'. + (check_tag_decl): Reject `constexpr'. + (check_function_type): Check constexpr functions. + * cp-tree.h (ds_constexpr): New cp_decl_spec enumerator. + (CLASSTYPE_LITERAL_P): New. + (lang_type_class::is_literal): New. + (lang_type_class::dummy): Adjust width. + (literal_type_p): Declare. + * parser.c (cp_parser_check_decl_spec): Print it. + (cp_parser_decl_specifier_seq): Accept "constexpr". + * semantics.c (validate_constexpr_fundecl): Define. + (literal_type_p): Define. + 2009-09-30 Jason Merrill <jason@redhat.com> * semantics.c (lambda_expr_this_capture): Fix default capture diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4c2441c2627..ab4a6a71abd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -112,11 +112,13 @@ framework extensions, you must include this file before toplev.h, not after. 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE) DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL) TYPE_MARKED_P (in _TYPE) + 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL) + 8: DECL_DECLARED_CONSTEXPR_P (in VAR_DECL, FUNCTION_DECL) Usage of TYPE_LANG_FLAG_?: 0: TYPE_DEPENDENT_P 1: TYPE_HAS_USER_CONSTRUCTOR. - 2: Unused + 2: unused 3: TYPE_FOR_JAVA. 4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR 5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE) @@ -1211,6 +1213,7 @@ struct GTY(()) lang_type_class { unsigned has_list_ctor : 1; unsigned non_std_layout : 1; unsigned lazy_move_ctor : 1; + unsigned is_literal : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If @@ -1219,7 +1222,7 @@ struct GTY(()) lang_type_class { /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ - unsigned dummy : 8; + unsigned dummy : 7; tree primary_base; VEC(tree_pair_s,gc) *vcall_indices; @@ -2189,6 +2192,10 @@ struct GTY(()) lang_decl { #define DECL_REPO_AVAILABLE_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p) +/* True if DECL is declared 'constexpr'. */ +#define DECL_DECLARED_CONSTEXPR_P(DECL) \ + DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (DECL)) + /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a template function. */ #define DECL_PRETTY_FUNCTION_P(NODE) \ @@ -2846,6 +2853,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P(TYPE) \ (UNSCOPED_ENUM_P (TYPE) || CP_INTEGRAL_TYPE_P (TYPE)) +/* True if the class type TYPE is a literal type. */ +#define CLASSTYPE_LITERAL_P(TYPE) \ + (LANG_TYPE_CLASS_CHECK (TYPE)->is_literal) + /* [basic.fundamental] Integral and floating types are collectively called arithmetic @@ -4190,6 +4201,7 @@ typedef enum cp_decl_spec { ds_explicit, ds_friend, ds_typedef, + ds_constexpr, ds_complex, ds_thread, ds_last @@ -4937,6 +4949,9 @@ extern tree begin_handler (void); extern void finish_handler_parms (tree, tree); extern void finish_handler (tree); extern void finish_cleanup (tree, tree); +extern bool literal_type_p (tree); +extern tree validate_constexpr_fundecl (tree); +extern tree ensure_literal_type_for_constexpr_object (tree); enum { BCS_NO_SCOPE = 1, diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 80238c18881..cb2827dfba4 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3231,7 +3231,7 @@ record_builtin_java_type (const char* name, int size) } else { /* "__java_float" or ""__java_double". */ - type = make_node (REAL_TYPE); + type = cxx_make_type (REAL_TYPE); TYPE_PRECISION (type) = - size; layout_type (type); } @@ -3397,7 +3397,7 @@ cxx_init_decl_processing (void) /* C++ extensions */ - unknown_type_node = make_node (UNKNOWN_TYPE); + unknown_type_node = cxx_make_type (UNKNOWN_TYPE); record_unknown_type (unknown_type_node, "unknown type"); /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */ @@ -3408,13 +3408,13 @@ cxx_init_decl_processing (void) TYPE_POINTER_TO (unknown_type_node) = unknown_type_node; TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node; - init_list_type_node = make_node (UNKNOWN_TYPE); + init_list_type_node = cxx_make_type (UNKNOWN_TYPE); record_unknown_type (init_list_type_node, "init list"); { /* Make sure we get a unique function type, so we can give its pointer type a name. (This wins for gdb.) */ - tree vfunc_type = make_node (FUNCTION_TYPE); + tree vfunc_type = cxx_make_type (FUNCTION_TYPE); TREE_TYPE (vfunc_type) = integer_type_node; TYPE_ARG_TYPES (vfunc_type) = NULL_TREE; layout_type (vfunc_type); @@ -3436,7 +3436,7 @@ cxx_init_decl_processing (void) abi_node = current_namespace; pop_namespace (); - global_type_node = make_node (LANG_TYPE); + global_type_node = cxx_make_type (LANG_TYPE); record_unknown_type (global_type_node, "global type"); /* Now, C++. */ @@ -3939,6 +3939,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) "and functions"); else if (saw_typedef) warning (0, "%<typedef%> was ignored in this declaration"); + else if (declspecs->specs[(int) ds_constexpr]) + error ("%<constexpr> cannot be used for type declarations"); } return declared_type; @@ -4181,6 +4183,9 @@ start_decl (const cp_declarator *declarator, error ("duplicate initialization of %qD", decl); if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false)) decl = field; + if (declspecs->specs[(int) ds_constexpr] + && !DECL_DECLARED_CONSTEXPR_P (field)) + error ("%qD declared %<constexpr%> outside its class", field); } } else @@ -4219,6 +4224,9 @@ start_decl (const cp_declarator *declarator, if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) permerror (input_location, "declaration of %q#D outside of class is not definition", decl); + + if (!ensure_literal_type_for_constexpr_object (decl)) + return error_mark_node; } was_public = TREE_PUBLIC (decl); @@ -4660,10 +4668,14 @@ check_for_uninitialized_const_var (tree decl) { tree type = TREE_TYPE (decl); + if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl) + && DECL_INITIAL (decl) == NULL) + error ("missing initializer for constexpr %qD", decl); + /* ``Unless explicitly declared extern, a const object does not have external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 */ - if (TREE_CODE (decl) == VAR_DECL + else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (type) != REFERENCE_TYPE && CP_TYPE_CONST_P (type) && !TYPE_NEEDS_CONSTRUCTING (type) @@ -7590,6 +7602,7 @@ grokdeclarator (const cp_declarator *declarator, bool type_was_error_mark_node = false; bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; bool template_type_arg = false; + bool constexpr_p = declspecs->specs[(int) ds_constexpr]; const char *errmsg; signed_p = declspecs->specs[(int)ds_signed]; @@ -8034,6 +8047,17 @@ grokdeclarator (const cp_declarator *declarator, type_quals = TYPE_UNQUALIFIED; if (declspecs->specs[(int)ds_const]) type_quals |= TYPE_QUAL_CONST; + /* A `constexpr' specifier used in an object declaration declares + the object as `const'. */ + if (constexpr_p) + { + if (innermost_code == cdk_function) + ; + else if (declspecs->specs[(int)ds_const] != 0) + error ("both %<const%> and %<constexpr%> cannot be used here"); + else + type_quals |= TYPE_QUAL_CONST; + } if (declspecs->specs[(int)ds_volatile]) type_quals |= TYPE_QUAL_VOLATILE; if (declspecs->specs[(int)ds_restrict]) @@ -8105,6 +8129,14 @@ grokdeclarator (const cp_declarator *declarator, error ("parameter declared %<auto%>"); type = error_mark_node; } + + /* Function parameters cannot be constexpr. If we saw one, moan + and pretend it wasn't there. */ + if (constexpr_p) + { + error ("a parameter cannot be declared %<constexpr%>"); + constexpr_p = 0; + } } /* Give error if `virtual' is used outside of class declaration. */ @@ -8412,6 +8444,21 @@ grokdeclarator (const cp_declarator *declarator, } } + /* It is not allowed to use `constexpr' in a function + declaration that is not a definition. + That is too strict, though. */ + if (constexpr_p && !funcdef_flag) + { + error ("the %<constexpr%> specifier cannot be used in " + "a function declaration that is not a definition"); + constexpr_p = false; + } + + /* A constexpr non-static member function is implicitly const. */ + if (constexpr_p && decl_context == FIELD && staticp == 0 + && sfk != sfk_constructor && sfk != sfk_destructor) + memfn_quals |= TYPE_QUAL_CONST; + arg_types = grokparms (declarator->u.function.parameters, &parms); @@ -8656,6 +8703,12 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } + /* It is not permitted to define a member function outside ist + membership class as `constexpr'. */ + if (constexpr_p) + error ("a constexpr function cannot be defined " + "outside of its class."); + if (TREE_CODE (sname) == IDENTIFIER_NODE && NEW_DELETE_OPNAME_P (sname)) /* Overloaded operator new and operator delete @@ -9123,6 +9176,8 @@ grokdeclarator (const cp_declarator *declarator, uqname, ctype); return error_mark_node; } + if (constexpr_p) + error ("a destructor cannot be %<constexpr%>"); } else if (sfk == sfk_constructor && friendp) { @@ -9143,7 +9198,8 @@ grokdeclarator (const cp_declarator *declarator, parms, unqualified_id, virtualp, flags, memfn_quals, raises, - friendp ? -1 : 0, friendp, publicp, inlinep, + friendp ? -1 : 0, friendp, publicp, + inlinep || constexpr_p, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); @@ -9235,6 +9291,7 @@ grokdeclarator (const cp_declarator *declarator, decl = do_friend (ctype, unqualified_id, decl, *attrlist, flags, funcdef_flag); + DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p; return decl; } else @@ -9296,6 +9353,9 @@ grokdeclarator (const cp_declarator *declarator, } else { + if (constexpr_p) + error ("non-static data member %qE declared %<constexpr%>", + unqualified_id); decl = build_decl (input_location, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; @@ -9390,7 +9450,7 @@ grokdeclarator (const cp_declarator *declarator, decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, virtualp, flags, memfn_quals, raises, 1, friendp, - publicp, inlinep, sfk, funcdef_flag, + publicp, inlinep || constexpr_p, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); if (decl == NULL_TREE) @@ -9487,6 +9547,10 @@ grokdeclarator (const cp_declarator *declarator, else if (storage_class == sc_static) DECL_THIS_STATIC (decl) = 1; + /* Don't forget constexprness. */ + if (VAR_OR_FUNCTION_DECL_P (decl)) + DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p; + /* Record constancy and volatility on the DECL itself . There's no need to do this when processing a template; we'll do this for the instantiated declaration based on the type of DECL. */ @@ -10983,7 +11047,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p) if (enumtype == error_mark_node) name = make_anon_name (); - enumtype = make_node (ENUMERAL_TYPE); + enumtype = cxx_make_type (ENUMERAL_TYPE); enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); } @@ -11426,6 +11490,10 @@ check_function_type (tree decl, tree current_function_parms) /* In a function definition, arg types must be complete. */ require_complete_types_for_parms (current_function_parms); + /* constexpr functions must have literal argument types and + literal return type. */ + validate_constexpr_fundecl (decl); + if (dependent_type_p (return_type)) return; if (!COMPLETE_OR_VOID_TYPE_P (return_type) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0ed7d2a9967..950d136f398 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2195,6 +2195,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs, "explicit", "friend", "typedef", + "constexpr", "__complex", "__thread" }; @@ -9030,7 +9031,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, switch (token->keyword) { /* decl-specifier: - friend */ + friend + constexpr */ case RID_FRIEND: if (!at_class_scope_p ()) { @@ -9045,6 +9047,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser, } break; + case RID_CONSTEXPR: + ++decl_specs->specs[(int) ds_constexpr]; + cp_lexer_consume_token (parser->lexer); + break; + /* function-specifier: inline virtual diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 86b4d9e43bc..d078642226b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3013,7 +3013,7 @@ make_pack_expansion (tree arg) pointer_set_destroy (ppd.visited); /* Create the pack expansion type for the base type. */ - purpose = make_node (TYPE_PACK_EXPANSION); + purpose = cxx_make_type (TYPE_PACK_EXPANSION); SET_PACK_EXPANSION_PATTERN (purpose, TREE_PURPOSE (arg)); PACK_EXPANSION_PARAMETER_PACKS (purpose) = parameter_packs; @@ -3028,7 +3028,9 @@ make_pack_expansion (tree arg) for_types = true; /* Build the PACK_EXPANSION_* node. */ - result = make_node (for_types ? TYPE_PACK_EXPANSION : EXPR_PACK_EXPANSION); + result = for_types + ? cxx_make_type (TYPE_PACK_EXPANSION) + : make_node (EXPR_PACK_EXPANSION); SET_PACK_EXPANSION_PATTERN (result, arg); if (TREE_CODE (result) == EXPR_PACK_EXPANSION) { @@ -3538,7 +3540,7 @@ current_template_args (void) tree vec = make_tree_vec (1); TREE_VEC_ELT (vec, 0) = make_pack_expansion (t); - t = make_node (TYPE_ARGUMENT_PACK); + t = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (t, vec); } } @@ -5575,7 +5577,7 @@ coerce_template_parameter_pack (tree parms, if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL || TREE_CODE (TREE_VALUE (parm)) == TEMPLATE_DECL) - argument_pack = make_node (TYPE_ARGUMENT_PACK); + argument_pack = cxx_make_type (TYPE_ARGUMENT_PACK); else { argument_pack = make_node (NONTYPE_ARGUMENT_PACK); @@ -6261,7 +6263,7 @@ lookup_template_class (tree d1, the values for the enumeration constants may involve template parameters. And, no one should be interested in the enumeration constants for such a type. */ - t = make_node (ENUMERAL_TYPE); + t = cxx_make_type (ENUMERAL_TYPE); SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type)); } } @@ -7816,7 +7818,7 @@ make_fnparm_pack (tree spec_parm) tree parmvec; tree parmtypevec; tree argpack = make_node (NONTYPE_ARGUMENT_PACK); - tree argtypepack = make_node (TYPE_ARGUMENT_PACK); + tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK); int i, len = list_length (spec_parm); /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ @@ -8147,7 +8149,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) else if (ARGUMENT_PACK_P (orig_arg)) { /* Substitute into each of the arguments. */ - new_arg = make_node (TREE_CODE (orig_arg)); + new_arg = TYPE_P (orig_arg) + ? cxx_make_type (TREE_CODE (orig_arg)) + : make_node (TREE_CODE (orig_arg)); SET_ARGUMENT_PACK_ARGS ( new_arg, @@ -10186,7 +10190,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: { - tree r = make_node (TREE_CODE (t)); + tree r = TYPE_P (t) + ? cxx_make_type (TREE_CODE (t)) + : make_node (TREE_CODE (t)); tree packed_out = tsubst_template_args (ARGUMENT_PACK_ARGS (t), args, @@ -13167,7 +13173,7 @@ type_unification_real (tree tparms, TREE_CONSTANT (arg) = 1; } else - arg = make_node (TYPE_ARGUMENT_PACK); + arg = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0)); @@ -13744,7 +13750,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, TREE_CONSTANT (result) = 1; } else - result = make_node (TYPE_ARGUMENT_PACK); + result = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (result, new_args); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 725bcc2966a..8199af0e693 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5203,6 +5203,87 @@ float_const_decimal64_p (void) return 0; } +/* Return true if T is a literal type. */ + +bool +literal_type_p (tree t) +{ + if (SCALAR_TYPE_P (t)) + return true; + if (CLASS_TYPE_P (t)) + return CLASSTYPE_LITERAL_P (t); + if (TREE_CODE (t) == ARRAY_TYPE) + return literal_type_p (strip_array_types (t)); + return false; +} + + +/* If DECL is a variable declared `constexpr', require its type + be literal. Return the DECL if OK, otherwise NULL. */ + +tree +ensure_literal_type_for_constexpr_object (tree decl) +{ + tree type = TREE_TYPE (decl); + if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl) + && !processing_template_decl && !literal_type_p (type)) + { + error ("the type %qT of constexpr variable %qD is not literal", + type, decl); + return NULL; + } + return decl; +} + +/* Return non-null if FUN certainly designates a valid constexpr function + declaration. Otherwise return NULL. Issue appropriate diagnostics + if necessary. Note that we only check the declaration, not the body + of the function. */ + +tree +validate_constexpr_fundecl (tree fun) +{ + tree rettype = NULL; + tree parm = NULL; + + /* Don't bother if FUN is not marked constexpr. */ + if (!DECL_DECLARED_CONSTEXPR_P (fun)) + return NULL; + + /* For a function template, we have absolutely no guarantee that all + instantiations will be constexpr. */ + if (TREE_CODE (fun) == TEMPLATE_DECL) + return NULL; + + parm = FUNCTION_FIRST_USER_PARM (fun); + for (; parm != NULL; parm = TREE_CHAIN (parm)) + { + tree type = TREE_TYPE (parm); + if (dependent_type_p (type)) + return NULL; + if (!literal_type_p (type)) + { + error ("parameter %q#D is not of literal type", parm); + return NULL; + } + } + + if (DECL_CONSTRUCTOR_P (fun)) + return fun; + + rettype = TREE_TYPE (TREE_TYPE (fun)); + if (dependent_type_p (rettype)) + return NULL; + if (!literal_type_p (rettype)) + { + error ("return type %qT of function %qD is not a literal type", + TREE_TYPE (TREE_TYPE (fun)), fun); + return NULL; + } + return fun; +} + + /* Constructor for a lambda expression. */ tree diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7476aa03a43..19a1270b76d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -639,7 +639,7 @@ build_cplus_array_type_1 (tree elt_type, tree index_type) else { /* Build a new array type. */ - t = make_node (ARRAY_TYPE); + t = cxx_make_type (ARRAY_TYPE); TREE_TYPE (t) = elt_type; TYPE_DOMAIN (t) = index_type; @@ -942,7 +942,6 @@ cp_build_qualified_type_real (tree type, && (TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result)) == TYPE_LANG_SPECIFIC (TYPE_CANONICAL (type)))) TYPE_LANG_SPECIFIC (TYPE_CANONICAL (result)) = NULL; - return result; } diff --git a/gcc/tree.h b/gcc/tree.h index a5a22f45643..ce841d548eb 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2597,6 +2597,7 @@ struct GTY(()) tree_decl_minimal { #define DECL_LANG_FLAG_5(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_5) #define DECL_LANG_FLAG_6(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_6) #define DECL_LANG_FLAG_7(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_7) +#define DECL_LANG_FLAG_8(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_8) /* Nonzero for a decl which is at file scope. */ #define DECL_FILE_SCOPE_P(EXP) \ @@ -2639,6 +2640,7 @@ struct GTY(()) tree_decl_common { unsigned lang_flag_5 : 1; unsigned lang_flag_6 : 1; unsigned lang_flag_7 : 1; + unsigned lang_flag_8 : 1; /* In LABEL_DECL, this is DECL_ERROR_ISSUED. In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */ @@ -2657,8 +2659,9 @@ struct GTY(()) tree_decl_common { unsigned decl_by_reference_flag : 1; /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_RESTRICTED_P. */ unsigned decl_restricted_flag : 1; + /* Padding so that 'off_align' can be on a 32-bit boundary. */ - unsigned decl_common_unused : 3; + unsigned decl_common_unused : 2; /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */ unsigned int off_align : 8; |