diff options
Diffstat (limited to 'gcc/cp/pt.cc')
-rw-r--r-- | gcc/cp/pt.cc | 129 |
1 files changed, 80 insertions, 49 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 3362a6f..acfeb81 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6952,14 +6952,22 @@ convert_nontype_argument_function (tree type, tree expr, { auto_diagnostic_group d; location_t loc = cp_expr_loc_or_input_loc (expr); - error_at (loc, "%qE is not a valid template argument for type %qT", - expr, type); - if (TYPE_PTR_P (type)) - inform (loc, "it must be the address of a function " - "with external linkage"); + tree c; + if (cxx_dialect >= cxx17 + && (c = cxx_constant_value (fn), + c == error_mark_node)) + ; else - inform (loc, "it must be the name of a function with " - "external linkage"); + { + error_at (loc, "%qE is not a valid template argument for " + "type %qT", expr, type); + if (TYPE_PTR_P (type)) + inform (loc, "it must be the address of a function " + "with external linkage"); + else + inform (loc, "it must be the name of a function with " + "external linkage"); + } } return NULL_TREE; } @@ -7402,22 +7410,22 @@ invalid_tparm_referent_p (tree type, tree expr, tsubst_flags_t complain) /* Null pointer values are OK in C++11. */; else { - if (VAR_P (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 true; - } + tree c; + if (!(complain & tf_error)) + ; + else if (cxx_dialect >= cxx17 + && (c = cxx_constant_value (expr), + c == error_mark_node)) + ; + else 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); else - { - 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 true; - } + error ("%qE is not a valid template argument for %qT " + "because it is not the address of a variable", + expr, type); + return true; } } return false; @@ -12699,7 +12707,17 @@ instantiate_class_template (tree type) determine_visibility (TYPE_MAIN_DECL (type)); } if (CLASS_TYPE_P (type)) - CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); + { + CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); + CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (type) + = CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (pattern); + CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (type) + = CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (pattern); + CLASSTYPE_REPLACEABLE_BIT (type) + = CLASSTYPE_REPLACEABLE_BIT (pattern); + CLASSTYPE_REPLACEABLE_COMPUTED (type) + = CLASSTYPE_REPLACEABLE_COMPUTED (pattern); + } pbinfo = TYPE_BINFO (pattern); @@ -14906,6 +14924,9 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, argvec = NULL_TREE; } + /* Make sure tsubst_decl substitutes all the parameters. */ + cp_evaluated ev; + tree closure = (lambda_fntype ? TYPE_METHOD_BASETYPE (lambda_fntype) : NULL_TREE); tree ctx = closure ? closure : DECL_CONTEXT (t); @@ -17250,13 +17271,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return error_mark_node; } - /* FIXME: TYPENAME_IS_CLASS_P conflates 'class' vs 'struct' vs 'union' - tags. TYPENAME_TYPE should probably remember the exact tag that - was written. */ + /* FIXME: TYPENAME_IS_CLASS_P conflates 'class' vs 'struct' tags. + TYPENAME_TYPE should probably remember the exact tag that + was written for -Wmismatched-tags. */ enum tag_types tag_type - = TYPENAME_IS_CLASS_P (t) ? class_type - : TYPENAME_IS_ENUM_P (t) ? enum_type - : typename_type; + = (TYPENAME_IS_CLASS_P (t) ? class_type + : TYPENAME_IS_UNION_P (t) ? union_type + : TYPENAME_IS_ENUM_P (t) ? enum_type + : typename_type); tsubst_flags_t tcomplain = complain | tf_keep_type_decl; tcomplain |= tst_ok_flag | qualifying_scope_flag; f = make_typename_type (ctx, f, tag_type, tcomplain); @@ -17278,10 +17300,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else return error_mark_node; } - else if (TYPENAME_IS_CLASS_P (t) && !CLASS_TYPE_P (f)) + else if (TYPENAME_IS_CLASS_P (t) && !NON_UNION_CLASS_TYPE_P (f)) { if (complain & tf_error) - error ("%qT resolves to %qT, which is not a class type", + error ("%qT resolves to %qT, which is not a non-union " + "class type", t, f); + else + return error_mark_node; + } + else if (TYPENAME_IS_UNION_P (t) && !UNION_TYPE_P (f)) + { + if (complain & tf_error) + error ("%qT resolves to %qT, which is not a union type", t, f); else return error_mark_node; @@ -17967,9 +17997,7 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain, return decl; /* Handle OpenMP iterators. */ - if (TREE_CODE (decl) == TREE_LIST - && TREE_PURPOSE (decl) - && TREE_CODE (TREE_PURPOSE (decl)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (decl)) { tree ret; if (iterator_cache[0] == TREE_PURPOSE (decl)) @@ -19573,7 +19601,8 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl) finish_static_assert (condition, message, STATIC_ASSERT_SOURCE_LOCATION (t), - /*member_p=*/false, /*show_expr_p=*/true); + /*member_p=*/false, /*show_expr_p=*/true, + CONSTEVAL_BLOCK_P (t)); } break; @@ -20138,7 +20167,14 @@ tsubst_stmt (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree op0 = RECUR (TREE_OPERAND (t, 0)); tree cond = RECUR (MUST_NOT_THROW_COND (t)); - RETURN (build_must_not_throw_expr (op0, cond)); + stmt = build_must_not_throw_expr (op0, cond); + if (stmt && TREE_CODE (stmt) == MUST_NOT_THROW_EXPR) + { + MUST_NOT_THROW_NOEXCEPT_P (stmt) = MUST_NOT_THROW_NOEXCEPT_P (t); + MUST_NOT_THROW_THROW_P (stmt) = MUST_NOT_THROW_THROW_P (t); + MUST_NOT_THROW_CATCH_P (stmt) = MUST_NOT_THROW_CATCH_P (t); + } + RETURN (stmt); } case EXPR_PACK_EXPANSION: @@ -20470,11 +20506,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = error_mark_node; else { - /* The body of a lambda-expression is not a subexpression of the - enclosing expression. Parms are to have DECL_CHAIN tsubsted, - which would be skipped if cp_unevaluated_operand. */ - cp_evaluated ev; - /* Fix the type of 'this'. For static and xobj member functions we use this to transport the lambda's closure type. It appears that in the regular case the @@ -20500,6 +20531,10 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* Let finish_function set this. */ DECL_DECLARED_CONSTEXPR_P (fn) = false; + /* The body of a lambda-expression is not a subexpression of the + enclosing expression. */ + cp_evaluated ev; + bool nested = cfun; if (nested) push_function_context (); @@ -31190,14 +31225,8 @@ alias_ctad_tweaks (tree tmpl, tree uguides) /* Substitute the deduced arguments plus the rewritten template parameters into f to get g. This covers the type, copyness, guideness, and explicit-specifier. */ - tree g; - { - /* Parms are to have DECL_CHAIN tsubsted, which would be skipped - if cp_unevaluated_operand. */ - cp_evaluated ev; - g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, complain, + tree g = tsubst_decl (DECL_TEMPLATE_RESULT (f), targs, complain, /*use_spec_table=*/false); - } if (g == error_mark_node) continue; DECL_NAME (g) = name; @@ -31627,7 +31656,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, /* Be permissive with equivalent alias templates. */ tree u = get_underlying_template (tmpl); auto_diagnostic_group d; - diagnostic_t dk = (u == tmpl) ? DK_ERROR : DK_PEDWARN; + const enum diagnostics::kind dk = ((u == tmpl) + ? diagnostics::kind::error + : diagnostics::kind::pedwarn); bool complained = emit_diagnostic (dk, input_location, 0, "alias template deduction only available " |