aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGabriel Dos Reis <gdr@cs.tamu.edu>2009-10-01 05:13:56 +0000
committerGabriel Dos Reis <gdr@gcc.gnu.org>2009-10-01 05:13:56 +0000
commit7ecbca9d02206b8fcba2710daa9e0a366af65a8b (patch)
treedcaed29421b884419d98bd0b4cb2308838e9ea60 /gcc
parentec30ab2c798327e9d538b985a410ba79487ae801 (diff)
downloadgcc-7ecbca9d02206b8fcba2710daa9e0a366af65a8b.zip
gcc-7ecbca9d02206b8fcba2710daa9e0a366af65a8b.tar.gz
gcc-7ecbca9d02206b8fcba2710daa9e0a366af65a8b.tar.bz2
tree.h (tree_decl_common::lang_flag_8): New.
gcc/ * 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. gcc/cp/ * 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. From-SVN: r152358
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-common.c1
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/cp/ChangeLog19
-rw-r--r--gcc/cp/cp-tree.h19
-rw-r--r--gcc/cp/decl.c86
-rw-r--r--gcc/cp/parser.c9
-rw-r--r--gcc/cp/pt.c26
-rw-r--r--gcc/cp/semantics.c81
-rw-r--r--gcc/cp/tree.c3
-rw-r--r--gcc/tree.h5
11 files changed, 232 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9653626..e80433a 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 baa3d35..4de92d0 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 6a02e04..c1655ae 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 f617fb1..a25f62b 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 4c2441c..ab4a6a7 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 80238c1..cb2827d 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 0ed7d2a..950d136 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 86b4d9e..d078642 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 725bcc2..8199af0 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 7476aa0..19a1270 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 a5a22f4..ce841d5 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;