diff options
Diffstat (limited to 'gcc-4.9/gcc/cp/pt.c')
-rw-r--r-- | gcc-4.9/gcc/cp/pt.c | 125 |
1 files changed, 74 insertions, 51 deletions
diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c index 318c32507..3951997b0 100644 --- a/gcc-4.9/gcc/cp/pt.c +++ b/gcc-4.9/gcc/cp/pt.c @@ -462,9 +462,13 @@ maybe_begin_member_template_processing (tree decl) bool nsdmi = TREE_CODE (decl) == FIELD_DECL; if (nsdmi) - decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) - ? CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (decl)) - : NULL_TREE); + { + tree ctx = DECL_CONTEXT (decl); + decl = (CLASSTYPE_TEMPLATE_INFO (ctx) + /* Disregard full specializations (c++/60999). */ + && uses_template_parms (ctx) + ? CLASSTYPE_TI_TEMPLATE (ctx) : NULL_TREE); + } if (inline_needs_template_parms (decl, nsdmi)) { @@ -5817,17 +5821,18 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (VAR_P (expr)) { - error ("%qD is not a valid template argument " - "because %qD is a variable, not the address of " - "a variable", - expr, expr); + if (complain & tf_error) + error ("%qD is not a valid template argument " + "because %qD is a variable, not the address of " + "a variable", expr, expr); return NULL_TREE; } if (POINTER_TYPE_P (expr_type)) { - error ("%qE is not a valid template argument for %qT " - "because it is not the address of a variable", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for %qT " + "because it is not the address of a variable", + expr, type); return NULL_TREE; } /* Other values, like integer constants, might be valid @@ -5842,23 +5847,24 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ? TREE_OPERAND (expr, 0) : expr); if (!VAR_P (decl)) { - error ("%qE is not a valid template argument of type %qT " - "because %qE is not a variable", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qE is not a variable", expr, type, decl); return NULL_TREE; } else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl)) { - error ("%qE is not a valid template argument of type %qT " - "because %qD does not have external linkage", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qD does not have external linkage", + expr, type, decl); return NULL_TREE; } else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none) { - error ("%qE is not a valid template argument of type %qT " - "because %qD has no linkage", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qD has no linkage", expr, type, decl); return NULL_TREE; } } @@ -5886,15 +5892,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type)) { - error ("%qE is not a valid template argument for type %qT " - "because of conflicts in cv-qualification", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because of conflicts in cv-qualification", expr, type); return NULL_TREE; } if (!real_lvalue_p (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because it is not an lvalue", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is not an lvalue", expr, type); return NULL_TREE; } @@ -5910,26 +5918,29 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) expr = TREE_OPERAND (expr, 0); if (DECL_P (expr)) { - error ("%q#D is not a valid template argument for type %qT " - "because a reference variable does not have a constant " - "address", expr, type); + if (complain & tf_error) + error ("%q#D is not a valid template argument for type %qT " + "because a reference variable does not have a constant " + "address", expr, type); return NULL_TREE; } } if (!DECL_P (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because it is not an object with external linkage", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is not an object with external linkage", + expr, type); return NULL_TREE; } if (!DECL_EXTERNAL_LINKAGE_P (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because object %qD has not external linkage", - expr, type, expr); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because object %qD has not external linkage", + expr, type, expr); return NULL_TREE; } @@ -5971,9 +5982,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (TREE_CODE (expr) == ADDR_EXPR) { - error ("%qE is not a valid template argument for type %qT " - "because it is a pointer", expr, type); - inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0)); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT " + "because it is a pointer", expr, type); + inform (input_location, "try using %qE instead", + TREE_OPERAND (expr, 0)); + } return NULL_TREE; } @@ -6011,13 +6026,16 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) provide a superior diagnostic. */ if (!same_type_p (TREE_TYPE (expr), type)) { - error ("%qE is not a valid template argument for type %qT " - "because it is of type %qT", expr, type, - TREE_TYPE (expr)); - /* If we are just one standard conversion off, explain. */ - if (can_convert_standard (type, TREE_TYPE (expr), complain)) - inform (input_location, - "standard conversions are not allowed in this context"); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, + TREE_TYPE (expr)); + /* If we are just one standard conversion off, explain. */ + if (can_convert_standard (type, TREE_TYPE (expr), complain)) + inform (input_location, + "standard conversions are not allowed in this context"); + } return NULL_TREE; } } @@ -6040,8 +6058,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (expr != nullptr_node) { - error ("%qE is not a valid template argument for type %qT " - "because it is of type %qT", expr, type, TREE_TYPE (expr)); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, TREE_TYPE (expr)); return NULL_TREE; } return expr; @@ -12638,13 +12657,17 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } else { - /* This can happen for a variable used in a late-specified - return type of a local lambda. Just make a dummy decl - since it's only used for its type. */ - if (cp_unevaluated_operand) - return tsubst_decl (t, args, complain); - gcc_assert (errorcount || sorrycount); - return error_mark_node; + /* This can happen for a variable used in a + late-specified return type of a local lambda, or for a + local static or constant. Building a new VAR_DECL + should be OK in all those cases. */ + r = tsubst_decl (t, args, complain); + if (decl_constant_var_p (r)) + /* A use of a local constant must decay to its value. */ + return integral_constant_value (r); + gcc_assert (cp_unevaluated_operand || TREE_STATIC (r) + || errorcount || sorrycount); + return r; } } } |