diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr84630.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/lambda-uneval13.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attr-expr1.C | 9 |
4 files changed, 48 insertions, 14 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c5b0a92..af7c67a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11571,6 +11571,8 @@ tsubst_attribute (tree t, tree *decl_p, tree args, val = tsubst_expr (val, args, complain, in_decl, /*integral_constant_expression_p=*/false); + if (val == error_mark_node) + return error_mark_node; if (val != TREE_VALUE (t)) return build_tree_list (TREE_PURPOSE (t), val); return t; @@ -11617,9 +11619,10 @@ tsubst_attributes (tree attributes, tree args, /* Apply any attributes which had to be deferred until instantiation time. DECL_P, ATTRIBUTES and ATTR_FLAGS are as cplus_decl_attributes; - ARGS, COMPLAIN, IN_DECL are as tsubst. */ + ARGS, COMPLAIN, IN_DECL are as tsubst. Returns true normally, + false on error. */ -static void +static bool apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, tree args, tsubst_flags_t complain, tree in_decl) { @@ -11628,12 +11631,12 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, tree *p; if (attributes == NULL_TREE) - return; + return true; if (DECL_P (*decl_p)) { if (TREE_TYPE (*decl_p) == error_mark_node) - return; + return false; p = &DECL_ATTRIBUTES (*decl_p); /* DECL_ATTRIBUTES comes from copy_node in tsubst_decl, and is identical to our attributes parameter. */ @@ -11668,9 +11671,11 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, t = *p; if (ATTR_IS_DEPENDENT (t)) { + *q = tsubst_attribute (t, decl_p, args, complain, in_decl); + if (*q == error_mark_node) + return false; *p = TREE_CHAIN (t); TREE_CHAIN (t) = NULL_TREE; - *q = tsubst_attribute (t, decl_p, args, complain, in_decl); while (*q) q = &TREE_CHAIN (*q); } @@ -11680,6 +11685,7 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, cplus_decl_attributes (decl_p, late_attrs, attr_flags); } + return true; } /* The template TMPL is being instantiated with the template arguments TARGS. @@ -14048,6 +14054,10 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, tsubst (DECL_FRIEND_CONTEXT (t), args, complain, in_decl)); + if (!apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, + args, complain, in_decl)) + return error_mark_node; + /* Set up the DECL_TEMPLATE_INFO for R. There's no need to do this in the special friend case mentioned above where GEN_TMPL is NULL. */ @@ -14127,8 +14137,6 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain, && !processing_template_decl) defaulted_late_check (r); - apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, - args, complain, in_decl); if (flag_openmp) if (tree attr = lookup_attribute ("omp declare variant base", DECL_ATTRIBUTES (r))) @@ -14228,7 +14236,9 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, /* The template parameters for this new template are all the template parameters for the old template, except the outermost level of parameters. */ + auto tparm_guard = make_temp_override (current_template_parms); DECL_TEMPLATE_PARMS (r) + = current_template_parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args, complain); @@ -14491,8 +14501,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (!DECL_TEMPLATE_PARM_P (r)) DECL_ARG_TYPE (r) = type_passed_as (type); - apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, - args, complain, in_decl); + if (!apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, + args, complain, in_decl)) + return error_mark_node; /* Keep track of the first new parameter we generate. That's what will be returned to the @@ -14581,8 +14592,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) finish_member_declaration. */ DECL_CHAIN (r) = NULL_TREE; - apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, - args, complain, in_decl); + if (!apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, + args, complain, in_decl)) + return error_mark_node; if (vec) TREE_VEC_ELT (vec, i) = r; @@ -14901,9 +14913,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) DECL_CHAIN (r) = NULL_TREE; - apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), - /*flags=*/0, - args, complain, in_decl); + if (!apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), + /*flags=*/0, + args, complain, in_decl)) + return error_mark_node; /* Preserve a typedef that names a type. */ if (is_typedef_decl (r) && type != error_mark_node) diff --git a/gcc/testsuite/g++.dg/cpp0x/pr84630.C b/gcc/testsuite/g++.dg/cpp0x/pr84630.C index 3c2b4e4..7d6361b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr84630.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr84630.C @@ -5,3 +5,4 @@ template <typename...> struct c { template <int> __attribute__((noinline([] {}))) int b(); // { dg-error "wrong number of arguments" } }; c<> a; +int i = a.b<42>(); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval13.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval13.C new file mode 100644 index 0000000..df908f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval13.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++20 } } + +template <class U> struct A +{ + template <class T> void spam(decltype([]{}) *s = nullptr) { } +}; + +void foo() +{ + A<int>().spam<int>(); +} diff --git a/gcc/testsuite/g++.dg/ext/attr-expr1.C b/gcc/testsuite/g++.dg/ext/attr-expr1.C new file mode 100644 index 0000000..990e710 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-expr1.C @@ -0,0 +1,9 @@ +// PR c++/95192 + +template<typename T> +__attribute__((assume_aligned(sizeof(int(T()))))) // { dg-message "function type" } +T *f(); + +void test21() { + void *p = f<void>() // { dg-error "no match" } +} |