aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog121
-rw-r--r--gcc/cp/class.c5
-rw-r--r--gcc/cp/constexpr.c55
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/decl.c38
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/lambda.c2
-rw-r--r--gcc/cp/name-lookup.c16
-rw-r--r--gcc/cp/parser.c13
-rw-r--r--gcc/cp/pt.c68
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/cp/tree.c20
12 files changed, 235 insertions, 117 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dadf6739ad1..91ddee0233c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,124 @@
+2015-04-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/65690
+ * tree.c (cp_build_qualified_type_real): Copy TYPE_ALIGN and
+ TYPE_USER_ALIGN.
+
+ PR c++/65690
+ * tree.c (build_cplus_array_type): Layout type before variants are
+ set, but copy over TYPE_SIZE and TYPE_SIZE_UNIT from the main
+ variant.
+
+2015-04-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/64085
+ * lambda.c (add_capture): Use dependent_type_p for capture by
+ reference too.
+
+2015-04-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65642
+ * constexpr.c (cxx_eval_pointer_plus_expression): Call
+ cxx_eval_constant_expression on the first operand.
+
+2015-04-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/65625
+ * decl.c (make_typename_type): Handle seeing a variable template.
+
+2015-04-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56100
+ * pt.c (instantiating_current_function_p): New.
+ * name-lookup.c (pushdecl_maybe_friend_1): Use it.
+ * cp-tree.h (instantiating_current_function_p): Declare.
+
+2015-04-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/65646
+ * decl.c (grokvardecl): Don't call check_explicit_specialization
+ for non-template members of a class template.
+
+2015-04-01 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65554
+ * class.c (finish_struct): Require that the second field of a
+ user-defined initializer_list be of size type.
+
+2015-03-31 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65390
+ * tree.c (build_cplus_array_type): Use dependent_type_p rather than
+ checking for constness.
+
+2015-03-30 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65398
+ * constexpr.c (cxx_fold_indirect_ref): Don't perform the
+ *(&A[i] p+ j) => A[i + j] transformation here.
+ (cxx_eval_pointer_plus_expression): New function.
+ (cxx_eval_constant_expression): Use it here.
+
+2015-03-27 Tobias Burnus <burnus@net-b.de>
+
+ PR c/65586
+ * parser.c (cp_parser_omp_for, cp_parser_omp_parallel,
+ cp_parser_omp_distribute, cp_parser_omp_teams, cp_parser_omp_target,
+ cp_parser_omp_declare): Don't show error for skipped omp pragmas with
+ -fopenmp-simd.
+
+2015-03-27 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65556
+ * semantics.c (finish_switch_cond): If the unlowered type is not an
+ enum, use the type of the condition.
+
+2015-03-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/65509
+ * decl.c (make_rtl_for_nonlocal_decl): Don't defer static
+ constants.
+
+2015-03-26 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR c++/65154
+ * init.c (build_vec_init): Fix initializing aggregates
+ with empty init list.
+
+2015-03-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/65525
+ * constexpr.c (potential_constant_expression_1): Handle MEM_REF.
+
+2015-03-25 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65558
+ * name-lookup.c (handle_namespace_attrs): Ignore abi_tag attribute
+ on an anonymous namespace.
+
+2015-03-25 Marek Polacek <polacek@redhat.com>
+
+ PR c++/61670
+ * class.c (remove_zero_width_bit_fields): Check for null DECL_SIZE.
+
+2015-03-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/65046
+ * cp-tree.h (NAMESPACE_IS_INLINE): Remove.
+ * parser.c (cp_parser_namespace_definition): Don't set it.
+ * name-lookup.c (handle_namespace_attrs): Check
+ DECL_NAMESPACE_ASSOCIATIONS instead.
+
+ PR c++/65498
+ * pt.c (get_mostly_instantiated_function_type): Just return the
+ type of the partially instantiated template in DECL_TI_TEMPLATE.
+
+2015-03-20 Marek Polacek <polacek@redhat.com>
+
+ PR c++/65398
+ * constexpr.c (cxx_fold_indirect_ref): Transform *(&A[i] p+ j) into
+ A[i + j].
+
2015-03-20 Marek Polacek <polacek@redhat.com>
PR c++/65072
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0518320d6b9..9f189fb5eaf 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5434,7 +5434,8 @@ remove_zero_width_bit_fields (tree t)
DECL_INITIAL (*fieldsp).
check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
to that width. */
- && integer_zerop (DECL_SIZE (*fieldsp)))
+ && (DECL_SIZE (*fieldsp) == NULL_TREE
+ || integer_zerop (DECL_SIZE (*fieldsp))))
*fieldsp = DECL_CHAIN (*fieldsp);
else
fieldsp = &DECL_CHAIN (*fieldsp);
@@ -6890,7 +6891,7 @@ finish_struct (tree t, tree attributes)
if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE)
{
f = next_initializable_field (DECL_CHAIN (f));
- if (f && TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
+ if (f && same_type_p (TREE_TYPE (f), size_type_node))
ok = true;
}
}
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 1b5f50cb494..f5be8dfb46c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2921,6 +2921,54 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
return NULL_TREE;
}
+/* Subroutine of cxx_eval_constant_expression.
+ Attempt to reduce a POINTER_PLUS_EXPR expression T. */
+
+static tree
+cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
+ bool lval, bool *non_constant_p,
+ bool *overflow_p)
+{
+ tree op00 = TREE_OPERAND (t, 0);
+ tree op01 = TREE_OPERAND (t, 1);
+ location_t loc = EXPR_LOCATION (t);
+
+ op00 = cxx_eval_constant_expression (ctx, op00, lval,
+ non_constant_p, overflow_p);
+
+ STRIP_NOPS (op00);
+ if (TREE_CODE (op00) != ADDR_EXPR)
+ return NULL_TREE;
+
+ op00 = TREE_OPERAND (op00, 0);
+
+ /* &A[i] p+ j => &A[i + j] */
+ if (TREE_CODE (op00) == ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (op00, 1)) == INTEGER_CST
+ && TREE_CODE (op01) == INTEGER_CST)
+ {
+ tree type = TREE_TYPE (op00);
+ t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (op00, 1));
+ tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (op00, 0)));
+ /* Don't fold an out-of-bound access. */
+ if (!tree_int_cst_le (t, nelts))
+ return NULL_TREE;
+ /* Make sure to treat the second operand of POINTER_PLUS_EXPR
+ as signed. */
+ op01 = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype,
+ cp_fold_convert (ssizetype, op01),
+ TYPE_SIZE_UNIT (type));
+ t = size_binop_loc (loc, PLUS_EXPR, op01, t);
+ t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (op00, 0),
+ t, NULL_TREE, NULL_TREE);
+ t = cp_build_addr_expr (t, tf_warning_or_error);
+ return cxx_eval_constant_expression (ctx, t, lval, non_constant_p,
+ overflow_p);
+ }
+
+ return NULL_TREE;
+}
+
/* Attempt to reduce the expression T to a constant value.
On failure, issue diagnostic and return error_mark_node. */
/* FIXME unify with c_fully_fold */
@@ -3226,6 +3274,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break;
case POINTER_PLUS_EXPR:
+ r = cxx_eval_pointer_plus_expression (ctx, t, lval, non_constant_p,
+ overflow_p);
+ if (r)
+ break;
+ /* else fall through */
+
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
@@ -4374,6 +4428,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
case ARRAY_RANGE_REF:
case MEMBER_REF:
case DOTSTAR_EXPR:
+ case MEM_REF:
binary:
for (i = 0; i < 2; ++i)
if (!RECUR (TREE_OPERAND (t, i), want_rval))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7111449da4b..2a904a5f4f4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -152,7 +152,6 @@ c-common.h, not after.
DECL_MUTABLE_P (in FIELD_DECL)
DECL_DEPENDENT_P (in USING_DECL)
LABEL_DECL_BREAK (in LABEL_DECL)
- NAMESPACE_IS_INLINE (in NAMESPACE_DECL)
1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
@@ -2657,10 +2656,6 @@ struct GTY(()) lang_decl {
#define LOCAL_CLASS_P(NODE) \
(decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE)
-/* 1 iff this NAMESPACE_DECL is an inline namespace. */
-#define NAMESPACE_IS_INLINE(NODE) \
- DECL_LANG_FLAG_0 (NAMESPACE_DECL_CHECK (NODE))
-
/* For a NAMESPACE_DECL: the list of using namespace directives
The PURPOSE is the used namespace, the value is the namespace
that is the common ancestor. */
@@ -5737,6 +5732,7 @@ extern tree get_mostly_instantiated_function_type (tree);
extern bool problematic_instantiation_changed (void);
extern void record_last_problematic_instantiation (void);
extern struct tinst_level *current_instantiation(void);
+extern bool instantiating_current_function_p (void);
extern tree maybe_get_template_decl_from_type_decl (tree);
extern int processing_template_parmlist;
extern bool dependent_type_p (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cb0f11f5749..c4731ae2416 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3480,9 +3480,9 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
name = TREE_OPERAND (name, 0);
- if (TREE_CODE (name) == TEMPLATE_DECL)
+ if (DECL_TYPE_TEMPLATE_P (name))
name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
- else if (TREE_CODE (name) == OVERLOAD)
+ if (TREE_CODE (name) != IDENTIFIER_NODE)
{
if (complain & tf_error)
error ("%qD is not a type", name);
@@ -6061,7 +6061,6 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
{
int toplev = toplevel_bindings_p ();
int defer_p;
- const char *filename;
/* Set the DECL_ASSEMBLER_NAME for the object. */
if (asmspec)
@@ -6109,32 +6108,9 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
DECL_EXPR is expanded. */
defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
- /* We try to defer namespace-scope static constants so that they are
- not emitted into the object file unnecessarily. */
- filename = LOCATION_FILE (input_location);
- if (!DECL_VIRTUAL_P (decl)
- && TREE_READONLY (decl)
- && DECL_INITIAL (decl) != NULL_TREE
- && DECL_INITIAL (decl) != error_mark_node
- && filename != NULL
- && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
- && toplev
- && !TREE_PUBLIC (decl))
- {
- /* Fool with the linkage of static consts according to #pragma
- interface. */
- struct c_fileinfo *finfo = get_fileinfo (filename);
- if (!finfo->interface_unknown && !TREE_PUBLIC (decl))
- {
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl) = finfo->interface_only;
- }
-
- defer_p = 1;
- }
- /* Likewise for template instantiations. */
- else if (DECL_LANG_SPECIFIC (decl)
- && DECL_IMPLICIT_INSTANTIATION (decl))
+ /* Defer template instantiations. */
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_IMPLICIT_INSTANTIATION (decl))
defer_p = 1;
/* If we're not deferring, go ahead and assemble the variable. */
@@ -8234,7 +8210,9 @@ grokvardecl (tree type,
DECL_INTERFACE_KNOWN (decl) = 1;
// Handle explicit specializations and instantiations of variable templates.
- if (orig_declarator)
+ if (orig_declarator
+ /* For GCC 5 fix 65646 this way. */
+ && current_tmpl_spec_kind (template_count) != tsk_none)
decl = check_explicit_specialization (orig_declarator, decl,
template_count, 0);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0274663c8f4..957a7a4e6e8 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3716,11 +3716,7 @@ build_vec_init (tree base, tree maxindex, tree init,
{
if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
{
- if (BRACE_ENCLOSED_INITIALIZER_P (init)
- && CONSTRUCTOR_NELTS (init) == 0)
- /* Reuse it. */;
- else
- init = build_constructor (init_list_type_node, NULL);
+ init = build_constructor (init_list_type_node, NULL);
CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
}
else
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index b160c8cb7ae..dd1c2d4337a 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -506,7 +506,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
if (by_reference_p)
{
type = build_reference_type (type);
- if (!real_lvalue_p (initializer))
+ if (!dependent_type_p (type) && !real_lvalue_p (initializer))
error ("cannot capture %qE by reference", initializer);
}
else
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index c845d521a53..e3f7cca4436 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -973,9 +973,8 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
/* If this is a locally defined typedef in a function that
is not a template instantation, record it to implement
-Wunused-local-typedefs. */
- if (current_instantiation () == NULL
- || (current_instantiation ()->decl != current_function_decl))
- record_locally_defined_typedef (x);
+ if (!instantiating_current_function_p ())
+ record_locally_defined_typedef (x);
}
/* Multiple external decls of the same identifier ought to match.
@@ -1277,7 +1276,8 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
old and new decls are type decls. */
|| (TREE_CODE (oldglobal) == TYPE_DECL
&& (!DECL_ARTIFICIAL (oldglobal)
- || TREE_CODE (x) == TYPE_DECL))))
+ || TREE_CODE (x) == TYPE_DECL)))
+ && !instantiating_current_function_p ())
/* XXX shadow warnings in outer-more namespaces */
{
if (warning_at (input_location, OPT_Wshadow,
@@ -3657,12 +3657,18 @@ handle_namespace_attrs (tree ns, tree attributes)
}
else if (is_attribute_p ("abi_tag", name))
{
- if (!NAMESPACE_IS_INLINE (ns))
+ if (!DECL_NAMESPACE_ASSOCIATIONS (ns))
{
warning (OPT_Wattributes, "ignoring %qD attribute on non-inline "
"namespace", name);
continue;
}
+ if (!DECL_NAME (ns))
+ {
+ warning (OPT_Wattributes, "ignoring %qD attribute on anonymous "
+ "namespace", name);
+ continue;
+ }
if (!args)
{
tree dn = DECL_NAME (ns);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 98d741f440a..4d6b479b497 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16233,7 +16233,6 @@ cp_parser_namespace_definition (cp_parser* parser)
if (is_inline)
{
tree name_space = current_namespace;
- NAMESPACE_IS_INLINE (name_space) = true;
/* Set up namespace association. */
DECL_NAMESPACE_ASSOCIATIONS (name_space)
= tree_cons (CP_DECL_CONTEXT (name_space), NULL_TREE,
@@ -30769,7 +30768,7 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
}
if (!flag_openmp) /* flag_openmp_simd */
{
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
@@ -30980,7 +30979,7 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
}
else if (!flag_openmp) /* flag_openmp_simd */
{
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -31243,7 +31242,7 @@ cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
}
if (!flag_openmp) /* flag_openmp_simd */
{
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
@@ -31322,7 +31321,7 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
}
if (!flag_openmp) /* flag_openmp_simd */
{
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
@@ -31467,7 +31466,7 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
}
else if (!flag_openmp) /* flag_openmp_simd */
{
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return false;
}
else if (strcmp (p, "data") == 0)
@@ -32443,7 +32442,7 @@ cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
}
if (!flag_openmp) /* flag_openmp_simd */
{
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return;
}
if (strcmp (p, "target") == 0)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ea826211996..28a85ebeeb7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -20748,62 +20748,8 @@ tsubst_enum (tree tag, tree newtag, tree args)
tree
get_mostly_instantiated_function_type (tree decl)
{
- tree fn_type;
- tree tmpl;
- tree targs;
- tree tparms;
- int parm_depth;
-
- tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
- targs = DECL_TI_ARGS (decl);
- tparms = DECL_TEMPLATE_PARMS (tmpl);
- parm_depth = TMPL_PARMS_DEPTH (tparms);
-
- /* There should be as many levels of arguments as there are levels
- of parameters. */
- gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs));
-
- fn_type = TREE_TYPE (tmpl);
-
- if (parm_depth == 1)
- /* No substitution is necessary. */
- ;
- else
- {
- int i;
- tree partial_args;
-
- /* Replace the innermost level of the TARGS with NULL_TREEs to
- let tsubst know not to substitute for those parameters. */
- partial_args = make_tree_vec (TREE_VEC_LENGTH (targs));
- for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i)
- SET_TMPL_ARGS_LEVEL (partial_args, i,
- TMPL_ARGS_LEVEL (targs, i));
- SET_TMPL_ARGS_LEVEL (partial_args,
- TMPL_ARGS_DEPTH (targs),
- make_tree_vec (DECL_NTPARMS (tmpl)));
-
- /* Make sure that we can see identifiers, and compute access
- correctly. */
- push_access_scope (decl);
-
- ++processing_template_decl;
- /* Now, do the (partial) substitution to figure out the
- appropriate function type. */
- fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
- --processing_template_decl;
-
- /* Substitute into the template parameters to obtain the real
- innermost set of parameters. This step is important if the
- innermost set of template parameters contains value
- parameters whose types depend on outer template parameters. */
- TREE_VEC_LENGTH (partial_args)--;
- tparms = tsubst_template_parms (tparms, partial_args, tf_error);
-
- pop_access_scope (decl);
- }
-
- return fn_type;
+ /* For a function, DECL_TI_TEMPLATE is partially instantiated. */
+ return TREE_TYPE (DECL_TI_TEMPLATE (decl));
}
/* Return truthvalue if we're processing a template different from
@@ -20827,6 +20773,16 @@ current_instantiation (void)
return current_tinst_level;
}
+/* Return TRUE if current_function_decl is being instantiated, false
+ otherwise. */
+
+bool
+instantiating_current_function_p (void)
+{
+ return (current_instantiation ()
+ && current_instantiation ()->decl == current_function_decl);
+}
+
/* [temp.param] Check that template non-type parm TYPE is of an allowable
type. Return zero for ok, nonzero for disallowed. Issue error and
warning messages under control of COMPLAIN. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f325e41f417..74af7e842c7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1165,6 +1165,8 @@ finish_switch_cond (tree cond, tree switch_stmt)
}
/* We want unlowered type here to handle enum bit-fields. */
orig_type = unlowered_expr_type (cond);
+ if (TREE_CODE (orig_type) != ENUMERAL_TYPE)
+ orig_type = TREE_TYPE (cond);
if (cond != error_mark_node)
{
/* Warn if the condition has boolean value. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ef53aff87f7..71c84ae38ef 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -822,10 +822,9 @@ build_cplus_array_type (tree elt_type, tree index_type)
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- bool dependent
- = (processing_template_decl
- && (dependent_type_p (elt_type)
- || (index_type && !TREE_CONSTANT (TYPE_MAX_VALUE (index_type)))));
+ bool dependent = (processing_template_decl
+ && (dependent_type_p (elt_type)
+ || (index_type && dependent_type_p (index_type))));
if (elt_type != TYPE_MAIN_VARIANT (elt_type))
/* Start with an array of the TYPE_MAIN_VARIANT. */
@@ -881,12 +880,19 @@ build_cplus_array_type (tree elt_type, tree index_type)
{
t = build_min_array_type (elt_type, index_type);
set_array_type_canon (t, elt_type, index_type);
+ if (!dependent)
+ {
+ layout_type (t);
+ /* Make sure sizes are shared with the main variant.
+ layout_type can't be called after setting TYPE_NEXT_VARIANT,
+ as it will overwrite alignment etc. of all variants. */
+ TYPE_SIZE (t) = TYPE_SIZE (m);
+ TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (m);
+ }
TYPE_MAIN_VARIANT (t) = m;
TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
TYPE_NEXT_VARIANT (m) = t;
- if (!dependent)
- layout_type (t);
}
}
@@ -1073,6 +1079,8 @@ cp_build_qualified_type_real (tree type,
{
t = build_variant_type_copy (t);
TYPE_NAME (t) = TYPE_NAME (type);
+ TYPE_ALIGN (t) = TYPE_ALIGN (type);
+ TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type);
}
}